Python:非';不冗余

Python:非';不冗余,python,for-loop,optimization,comparison,graph-algorithm,Python,For Loop,Optimization,Comparison,Graph Algorithm,假设我有一个列表嵌套在dict的一个键中,比如: d = {'people':['John', 'Carry', 'Joe', 'Greg', 'Carl', 'Gene']} 我想将列表中的人相互比较,这样我就可以制作一个图表,将以相同首字母开头的名字连接起来 我提出了一个嵌套for循环来尝试解决这个问题: for subject in d.keys(): for word1 in d[people]: for word2 in d[people]:

假设我有一个列表嵌套在dict的一个键中,比如:

d = {'people':['John', 'Carry', 'Joe', 'Greg', 'Carl', 'Gene']}
我想将列表中的人相互比较,这样我就可以制作一个图表,将以相同首字母开头的名字连接起来

我提出了一个嵌套for循环来尝试解决这个问题:

for subject in d.keys():
        for word1 in d[people]:
            for word2 in d[people]:
                if word1[0] == word2[0]:
                    g.connectThem(word1,word2)

但是嵌套的for循环可能会变得多余,因为它会进行两次相同的比较。是否有任何方法使其在比较方面不存在冗余

您可以使用
itertools.compositions

for pair in itertools.combinations(d['people'], 2):
    first, second = pair
    if first[0] == second[0]:
        g.connectThem(first, second)
[('John', 'Carry'), ('John', 'Joe'), ('John', 'Greg'), ('John', 'Carl'), ('John', 'Gene'),
 ('Carry', 'Joe'), ('Carry', 'Greg'), ('Carry', 'Carl'), ('Carry', 'Gene'),
 ('Joe', 'Greg'), ('Joe', 'Carl'), ('Joe', 'Gene'),
 ('Greg', 'Carl'), ('Greg', 'Gene'),
 ('Carl', 'Gene')]
这些是由
组合产生的对

for pair in itertools.combinations(d['people'], 2):
    first, second = pair
    if first[0] == second[0]:
        g.connectThem(first, second)
[('John', 'Carry'), ('John', 'Joe'), ('John', 'Greg'), ('John', 'Carl'), ('John', 'Gene'),
 ('Carry', 'Joe'), ('Carry', 'Greg'), ('Carry', 'Carl'), ('Carry', 'Gene'),
 ('Joe', 'Greg'), ('Joe', 'Carl'), ('Joe', 'Gene'),
 ('Greg', 'Carl'), ('Greg', 'Gene'),
 ('Carl', 'Gene')]
请注意,您没有重复问题(通过颠倒对的顺序)。
假设你的
连接他们
功能工作,这应该会产生你想要的行为。

如果你想比较列表中的人,这样我就可以制作一个图表来连接以相同首字母开头的名字。然后使用dict和单次传递
d[“people”]
,其中使用姓名的首字母作为键,因此解决方案是
0(n)
,并且明显比二次获得所有组合更有效,这会创建大多数不必要的配对:

d = {"people":['John', 'Carry', 'Joe', 'Greg', 'Carl', 'Gene']}

from collections import defaultdict

my_d = defaultdict(list)

for v in d["people"]:
    my_d[v[0]].append(v)
print(my_d)
defaultdict(<type 'list'>, {'C': ['Carry', 'Carl'], 'J': ['John', 'Joe'], 'G': ['Greg', 'Gene']})
for group in my_d.itervalues():
    for ind, n1 in enumerate(group):
        for n2 in group[ind+1:]:
            print(n1,n2)
('Carry', 'Carl')
('John', 'Joe')
('Greg', 'Gene')
完全不使用itertools,我们可以看到,因为我们的线性过程创建了一个组的dict,所以我们可以简单地在out dict中的每个值列表上循环,并创建uniques对:

d = {"people":['John', 'Carry', 'Joe', 'Greg', 'Carl', 'Gene']}

from collections import defaultdict

my_d = defaultdict(list)

for v in d["people"]:
    my_d[v[0]].append(v)
print(my_d)
defaultdict(<type 'list'>, {'C': ['Carry', 'Carl'], 'J': ['John', 'Joe'], 'G': ['Greg', 'Gene']})
for group in my_d.itervalues():
    for ind, n1 in enumerate(group):
        for n2 in group[ind+1:]:
            print(n1,n2)
('Carry', 'Carl')
('John', 'Joe')
('Greg', 'Gene')

你教会了我一些非常有用的东西。我很感激。我将来肯定会使用defaultdict。虽然这并不完全是我想要的,但你确实用一种优化的方法来解决我正在使用的具体示例。非常感谢!这实际上会做完全相同的事情,只是通过首先对组进行线性传递,然后获得组合,效率会大大提高。对于一个大的列表,仅仅使用组合会扩展得非常糟糕。你是对的。再次感谢你给我看defaultdict。感谢你指出了组合。他们肯定是我在这个例子中寻找的!