将Pythonic循环方法转换为嵌套循环

时间:2017-09-13 12:41:26

标签: python python-2.7 loops nested-loops python-2.x

我是Python的初学者。我想了解循环的Pythonic方法,因为我很长一段时间都是C编码器。给出以下两行:

{k: v for out_d in outs for k, v in out_d.iteritems()}
[{} for i in range(nthreads)]

有人可以将其分解,以便它遵循嵌套循环的C标准方法吗?

4 个答案:

答案 0 :(得分:2)

my_dict = {k: v for out_d in outs for k, v in out_d.iteritems()}

# is equivalent to

my_dict = {}
for out_d in outs:
    for key, value in out_d.iteritems():
        my_dict[key] = value



my_list = [{} for i in range(nthreads)]

# is equivalent to

my_list = []
for i in range(nthreads):
    my_list.append({})

答案 1 :(得分:1)

等价物是:

res = {}
for out_d in outs:
    for k, v in out_d.iteritems():
        res[k] = v

res = []
for i in range(nthreads):
    res.append({})

请注意,您可以通过使用不同的缩进来相对简单地找到这些:

{k: v for out_d in outs for k, v in out_d.iteritems()}

=>

{k: v 
 for out_d in outs 
 for k, v in out_d.iteritems()}

=>

{        k: v 
 for out_d in outs 
     for k, v in out_d.iteritems()}

唯一棘手的一点是,第一个语句k: v实际上位于最内层循环中,但所有后面的表达式按照" loopy" -equivalent的顺序排序。根据理解的类型,第一个陈述也会有所不同。

对于字典理解它是the_dict[key] = value而不是key: value,对于列表理解它是the_list.append(value),对于集合理解它是the_set.add(value) yield value 1}}。生成器表达式更复杂,因为你必须编写一个id contract Start Date End Date 1000 1 2017/08/31 9999/12/31 id contract Start Date End Date 1000 1 2017/08/31 2017/09/16 1000 2 2017/09/16 9999/12/31 id contract Start Date End Date 1000 1 2017/08/31 2017/09/14 1000 2 2017/09/16 2017/09/16 1000 3 2017/09/14 9999/12/31

的函数

答案 2 :(得分:1)

for key, value in out_d.iteritems()

- iteritems()遍历字典的键/值,因此out_d必须是字典

for out_d in outs

- for out_d in outs将遍历outs中的迭代器,基于前一个我们可以假设这是一个字典列表

{k:v}

- 这会使用k,v

的值创建新的字典理解

所有在一起:

为列表输出中的每个out_d创建字典out_d中每个键值,值k,v的字典理解

new_dict = {}
for dictionary in outs:
    for key, value in dictionary.iteritems()
        new_dict[key] = value

答案 3 :(得分:0)

Python:列表理解

Python支持名为" list comprehensions"的概念。它可以用于以非常自然,简单的方式构建列表,就像数学家习惯一样。

以下是在数学中描述列表(或集合,或元组或向量)的常用方法。

S = {x² : x in {0 ... 9}}
V = (1, 2, 4, 8, ..., 2¹²)
M = {x | x in S and x even}

你可能从学校的数学课上了解上述内容。在Python中,你几乎可以像数学家那样编写这些表达式,而不必记住任何特殊的神秘语法。

这是你在Python中执行上述操作的方法:

>>> S = [x**2 for x in range(10)]
>>> V = [2**i for i in range(13)]
>>> M = [x for x in S if x % 2 == 0]
>>> 
>>> print S; print V; print M
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096]
[0, 4, 16, 36, 64]

我确定你想看一个更复杂的例子。 :-)以下是另一种计算素数的方法。有趣的是,我们首先使用单个列表理解构建非素数列表,然后使用另一个列表理解来获得"逆"列表,这是素数。

>>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
>>> primes = [x for x in range(2, 50) if x not in noprimes]
>>> print primes
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

注意:您可以将列表推导嵌套在彼此之内,因此您可以使用单个语句编写上述示例(无需临时变量" noprimes")。但是,这些线条往往会变长并且可读性较差,因此不建议这样做。

当然,列表推导不仅适用于数字。列表可以包含任何类型的元素,包括字符串,嵌套列表和函数。您甚至可以在列表中混合使用不同的类型。

以下内容适用于字符串列表并生成列表列表。每个子列表包含两个字符串和一个整数。

>>> words = 'The quick brown fox jumps over the lazy dog'.split()
>>> print words
['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']
>>> 
>>> stuff = [[w.upper(), w.lower(), len(w)] for w in words]
>>> for i in stuff:
...     print i
... 
['THE', 'the', 3]
['QUICK', 'quick', 5]
['BROWN', 'brown', 5]
['FOX', 'fox', 3]
['JUMPS', 'jumps', 5]
['OVER', 'over', 4]
['THE', 'the', 3]
['LAZY', 'lazy', 4]
['DOG', 'dog', 3]
>>> 
>>> stuff = map(lambda w: [w.upper(), w.lower(), len(w)], words)
>>> for i in stuff:
...     print i
... 
['THE', 'the', 3]
['QUICK', 'quick', 5]
['BROWN', 'brown', 5]
['FOX', 'fox', 3]
['JUMPS', 'jumps', 5]
['OVER', 'over', 4]
['THE', 'the', 3]
['LAZY', 'lazy', 4]
['DOG', 'dog', 3]

上面的例子也证明了你可以用map()和lambda函数做同样的事情。但是,有些情况下您不能使用map()并且必须使用列表推导,反之亦然。当你可以使用两者时,通常最好使用列表理解,因为这在大多数情况下更有效,更容易阅读。

当构造规则过于复杂而无法使用"表示"时,不能使用列表推导。和"如果"语句,或者构造规则是否可以在运行时动态更改。在这种情况下,最好将map()和/或filter()与适当的函数一起使用。当然,您可以将其与列表推导相结合。