【问题标题】:copying iterators and producing unordered self-cartesian product复制迭代器并产生无序的自笛卡尔积
【发布时间】:2011-07-13 04:23:19
【问题描述】:

假设我有一个列表,我想在不考虑顺序的情况下生成所有唯一元素对的列表。一种方法是:

mylist = ['W','X','Y','Z']
for i in xrange(len(mylist)):
    for j in xrange(i+1,len(mylist)):
        print mylist[i],mylist[j]
W X
W Y
W Z
X Y
X Z
Y Z

我想用迭代器来做这个,我想到了以下,即使它不简洁:

import copy
it1 = iter(mylist)
for a in it1:
    it2 = copy.copy(it1)
    for b in it2:
        print a,b

但这甚至行不通。使用迭代器或 zip 等执行此操作的更 Pythonic 和更有效的方法是什么?

【问题讨论】:

  • 今天第二次看到这个作业题了。
  • @Apalala,感谢您的反对,但我实际上想要我正在编码的东西的答案,并且在搜索时找不到任何其他类似的问题。

标签: python list iterator cartesian-product


【解决方案1】:

这已经完成并包含在 Python 2.6 的标准库中:

import itertools

mylist = ['W', 'X', 'Y', 'Z']
for pair in itertools.combinations(mylist, 2):
    print pair        # pair is a tuple of 2 elements

对我来说似乎很 Pythonic ;-)

请注意,即使您要计算大量组合,combinations() 函数也会返回一个迭代器,以便您可以立即开始打印它们。请参阅docs

此外,您将结果称为列表与其自身之间的笛卡尔积,但这并不完全正确:笛卡尔积将具有 16 个元素 (4x4)。您的输出是其中的一个子集,即只有列表值的 2 元素 combinations(不允许重复)。

【讨论】:

  • 你说得对,我应该称之为组合,这可能会给我答案!
【解决方案2】:

@Cameron 的回答是正确的。

我只是想指出这一点

for i in range(len(mylist)):
    do_something_to(mylist[i])

非常不符合 Python 风格;如果您的操作是只读的(不必存储回数组),请执行

for i in mylist:
    do_something_to(i)

否则

mylist = [do_something_to(i) for i in mylist]

【讨论】:

  • 我同意,但我在做 range(len(mylist)) 因为我需要参考索引。
  • 你也可以使用枚举。例如:“for index, value in enumerate(mylist): print(index, value)”
猜你喜欢
  • 2017-09-28
  • 1970-01-01
  • 2012-08-27
  • 2023-03-09
  • 1970-01-01
  • 2016-10-08
  • 2021-09-05
  • 2011-01-26
  • 1970-01-01
相关资源
最近更新 更多