我想在python中生成一个列表,如下所示 -
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25 .....]
你可能已经想通了,它只不过是n, n*n
我尝试在python中编写这样的列表推导,如下所示 -
lst_gen = [i, i*i for i in range(1, 10)]
但是这样做会产生语法错误。
通过列表理解生成上述列表的好方法是什么?
答案 0 :(得分:39)
使用itertools.chain.from_iterable
:
>>> from itertools import chain
>>> list(chain.from_iterable((i, i**2) for i in xrange(1, 6)))
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25]
或者您也可以使用generator功能:
>>> def solve(n):
... for i in xrange(1,n+1):
... yield i
... yield i**2
>>> list(solve(5))
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25]
答案 1 :(得分:10)
问题是陈旧的,但只是对于好奇的读者,我提出了另一种可能性: 如第一篇文章所述,您可以从数字列表中轻松制作一对(i,i ** 2)。然后你想要压扁这对夫妻。因此,只需在理解中添加展平操作。
[x for i in range(1, 10) for x in (i,i**2)]
答案 2 :(得分:6)
一个鲜为人知的技巧:列表推导可以有多个for子句。
例如:
>>> [10*x+y for x in range(4) for y in range(3)]
[0, 1, 2, 10, 11, 12, 20, 21, 22, 30, 31, 32]
在您的特定情况下,您可以这样做:
>>> [x*x if y else x for x in range(5) for y in range(2)]
[0, 0, 1, 1, 2, 4, 3, 9, 4, 16]
答案 3 :(得分:5)
lst_gen = sum([(i, i*i) for i in range(1, 10)],())
哦,我应该提到这个总和可能打破了一个迭代规则:(
答案 4 :(得分:5)
列表推导一次生成一个元素。相反,您的选择是将循环更改为一次只生成一个值:
[(i//2)**2 if i % 2 else i//2 for i in range(2, 20)]
或生成元组,然后使用itertools.chain.from_iterable()
展平列表:
from itertools import chain
list(chain.from_iterable((i, i*i) for i in range(1, 10)))
输出:
>>> [(i//2)**2 if i % 2 else i//2 for i in range(2, 20)]
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25, 6, 36, 7, 49, 8, 64, 9, 81]
>>> list(chain.from_iterable((i, i*i) for i in range(1, 10)))
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25, 6, 36, 7, 49, 8, 64, 9, 81]
答案 5 :(得分:3)
您可以创建列表列表,然后使用reduce来加入它们。
print [[n,n*n] for n in range (10)]
[[0,0],[1,1],[2,4],[3,9],[4,16],[5,25],[6,36],[7,49 ],[8,64],[9,81]]
print reduce(lambda x1,x2:x1+x2,[[n,n*n] for n in range (10)])
[0,0,1,1,2,4,3,9,14,5,25,6,36,7,49,8,64,9,81]
print reduce(lambda x1,x2:x1+x2,[[n**e for e in range(1,4)]\
for n in range (1,10)])
[1,1,1,2,4,8,3,9,27,4,16,64,5,25,125,6,36,216,7,49,343,8,64, 512,9,81,729]
Reduce采用一个可调用的表达式,该表达式接受两个参数并通过从前两个项开始处理序列。然后将最后一个表达式的结果用作后续调用中的第一项。在这种情况下,每个列表将一个接一个地添加到列表列表中的第一个列表中,然后返回该列表。
列表推导使用由“ var 序列”表达式中定义的变量和序列隐式调用具有lambda表达式的map。以下是同样的事情。
map(lambda n:[n,n*n],range(1,10))
[[1,1],[2,4],[3,9],[4,16],[5,25],[6,36],[7,49],[8,64 ],[9,81]]
我不知道用于reduce的更自然的python表达式。
答案 6 :(得分:2)
另一种选择,似乎对某些
有悖常理>>> from itertools import izip, tee
>>> g = xrange(1, 11)
>>> x, y = tee(g)
>>> y = (i**2 for i in y)
>>> z = izip(x, y)
>>> output = []
>>> for k in z:
... output.extend(k)
...
>>> print output
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25, 6, 36, 7, 49, 8, 64, 9, 81, 10, 100]
答案 7 :(得分:1)
另一种选择:
reduce(lambda x,y: x + [y, y*y], range(1,10), [])
答案 8 :(得分:1)
>>> lst_gen = [[i, i*i] for i in range(1, 10)]
>>>
>>> lst_gen
[[1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]
>>>
>>> [num for elem in lst_gen for num in elem]
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25, 6, 36, 7, 49, 8, 64, 9, 81]
这是我的参考 http://docs.python.org/2/tutorial/datastructures.html
答案 9 :(得分:1)
这个帖子中有很多技巧。这是另一个使用没有进口的单线性发电机
x = (lamdba : [[(yield i), (yield i**2)] for i in range(10)])()
编辑: 这将引发Python 3.7中的DeprecatedWarning和Python 3.8中的SyntaxError: https://docs.python.org/dev/whatsnew/3.7.html#deprecated-python-behavior
答案 10 :(得分:1)
一个简单的可能是:
[i ** j for i in range(1, 6) for j in [1, 2]]
关于任务和列表组件替换两个嵌套循环的事实非常明确(而正如其他答案所示,可以说是可以展平的)。 输出:
[1, 1, 2, 4, 3, 9, 4, 16, 5, 25]
答案 11 :(得分:0)
试试这两个班轮
lst = [[i, i*i] for i in range(10)]
[lst.extend(i) for i in lst]
根据需要更改数学。
更好的
#Change my_range to be the number you want range() function of
start = 1
my_range = 10
lst = [i/2 if i % 2 == 0 else ((i-1)/2)**2 for i in range(start *2, my_range*2 - 1)]
答案 12 :(得分:0)
如上所述,itertools是要走的路。我就是这样做的,我发现它更清楚:
[i if turn else i*i for i,turn in itertools.product(range(1,10), [True, False])]