Python中的高级分组

2024-03-29 04:40:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我有点脑筋急转弯,给出这样的数据:

data = [('topic1', (['apples', 'oranges'], 0.14975108213820515)),
       ('topic2', (['oranges', 'raisins'], 0.14975108213820515)),
       ('topic3', (['grapes', 'raisins'], 0.14975108213820515)),
       ('topic4', (['trees', 'flowers'], 0.14975108213820515))]

我想根据数组中(元组第二个元素的第一个元素中)是否至少有一个文本是公共的来连接主题。所以在上述情况下:

topic1 is connected to topic2 
topic2 is connected to topic1 and topic3
topic3 is connected to topic2
topic4 is unconnected

理想情况下,我的输出如下所示:

output = [(topic1,topic2), 
         (topic1,topic2, topic3),
         (topic3, topic2),
         (topic4)]

所以,给定像data这样的输入,我怎么能得到像output这样的输出。我认为itertools可能会牵涉其中,但我真的被困在这一点上。你知道吗


Tags: to数据元素outputdataisconnectedoranges
3条回答

一个简单的双for循环:

>>> for i in range(len(data)):
...     x = set(data[i][1][0])
...     for j in range(len(data)):
...         if len(x & set(data[j][1][0]))>=1:
...             print data[j][0],             # for python 3 use print()
...     print
... 
topic1 topic2
topic1 topic2 topic3
topic2 topic3
topic4

一种有效的方法是使用sets

>>> set1= set(['apples', 'oranges'])
>>> set2= set(['oranges', 'raisins'])
>>> print len(set1.intersection(set2))
1

所以,基本上:

  • 为每个主题的文本创建一个集合
  • 对于每个主题,迭代每个其他主题并检查它们的文本集的交集len

topic_text_sets= {topic:set(text) for topic,(text,_) in data}
topic_related= {}
for topic1, text1 in topic_text_sets.iteritems():
    related= [topic2 for topic2, text2 in topic_text_sets.iteritems() if topic1!=topic2 and len(text1.intersection(text2))>0]
    print related

topic1 ['topic2']
topic3 ['topic2']
topic2 ['topic1', 'topic3']
topic4 []

您可以创建一个包含列表的字典来捕获连接:

connections = {}
for topic, (conns, some_number) in data:
    for conn in conns:
        connections.setdefault(conn, set()).add(topic)

这将连接值映射到主题集。你知道吗

现在可以查找反向连接;如果顺序不重要,只需获取所有连接值集的并集:

output = [tuple(set().union(*(connections[c] for c in conns))) 
          for topic, (conns, some_number) in data]

演示:

>>> data = [('topic1', (['apples', 'oranges'], 0.14975108213820515)),
...        ('topic2', (['oranges', 'raisins'], 0.14975108213820515)),
...        ('topic3', (['grapes', 'raisins'], 0.14975108213820515)),
...        ('topic4', (['trees', 'flowers'], 0.14975108213820515))]
>>> connections = {}
>>> for topic, (conns, some_number) in data:
...     for conn in conns:
...         connections.setdefault(conn, set()).add(topic)
... 
>>> [tuple(set().union(*(connections[c] for c in conns))) 
...               for topic, (conns, some_number) in data]
[('topic1', 'topic2'), ('topic1', 'topic3', 'topic2'), ('topic3', 'topic2'), ('topic4',)]
>>> from pprint import pprint
>>> pprint(_)
[('topic1', 'topic2'),
 ('topic1', 'topic3', 'topic2'),
 ('topic3', 'topic2'),
 ('topic4',)]

否则,先从集合中移除topic到前面:

output = [(topic,) + tuple(set().union(*(connections[c] for c in conns)) - {topic}) 
          for topic, (conns, some_number) in data]

>>> [(topic,) + tuple(set().union(*(connections[c] for c in conns)) - {topic}) 
...               for topic, (conns, some_number) in data]
[('topic1', 'topic2'), ('topic2', 'topic1', 'topic3'), ('topic3', 'topic2'), ('topic4',)]
>>> pprint(_)
[('topic1', 'topic2'),
 ('topic2', 'topic1', 'topic3'),
 ('topic3', 'topic2'),
 ('topic4',)]

相关问题 更多 >