在列表推导的迭代中我的逻辑出了什么问题?

时间:2017-10-01 05:35:34

标签: python list iteration

我原以为['jelly%s'% x*x for x in range(1,11)]会给我一个jellyx * x列表,但它会返回以下值。

['jelly1', 'jelly2jelly2', 'jelly3jelly3jelly3', 'jelly4jelly4jelly4jelly4', 'jelly5jelly5jelly5jelly5jelly5', 'jelly6jelly6jelly6jelly6jelly6jelly6', 'jelly7jelly7jelly7jelly7jelly7jelly7jelly7', 'jelly8jelly8jelly8jelly8jelly8jelly8jelly8jelly8', 'jelly9jelly9jelly9jelly9jelly9jelly9jelly9jelly9jelly9', 'jelly10jelly10jelly10jelly10jelly10jelly10jelly10jelly10jelly10jelly10']

代码出了什么问题?

2 个答案:

答案 0 :(得分:3)

问题在于表达式:

'jelly%s'% x*x

这相当于:

('jelly%s'%x)*x

因为%*运算符具有same precedence

优先级仅表示在表达式中首先评估哪些运算符。具有较高优先级的运算符在具有较低优先级的运算符之前“绑定”,具有相同优先级的运算符从左到右进行求值。这类似于数学,所以:

>>> 1 + 10 * 10 # * has higher precedence
101
>>> (1 + 10) * 10 # we can force + to happen first
110

注意,算术运算符的优先级是数学算术运算符的典型值。

最后,你可能不知道,但是对于序列类型(包括strlisttuple*运算符会导致“重复操作” ,所以:

>>> 'juan'*1
'juan'
>>> 'juan'*2
'juanjuan'
>>> 'juan'*3
'juanjuanjuan'

所以,为了得到你想要的东西,试试:

['jelly%s'% (x*x) for x in range(1,11)]

或者,您可以在字符串上使用.format方法:

>>> ['jelly{}'.format(x*x) for x in range(1,11)]
['jelly1', 'jelly4', 'jelly9', 'jelly16', 'jelly25', 'jelly36', 'jelly49', 'jelly64', 'jelly81', 'jelly100']

或者甚至更好,在Python 3.6中使用f-string:

>>> [f'jelly{x*x}' for x in range(1,11)]
['jelly1', 'jelly4', 'jelly9', 'jelly16', 'jelly25', 'jelly36', 'jelly49', 'jelly64', 'jelly81', 'jelly100']

答案 1 :(得分:2)

你也可以这样做:

['jelly%s' % num for num in [x*x for x in range(1,11)]]

会给:

OUT : ['jelly1', 'jelly4', 'jelly9', 'jelly16', 'jelly25', 'jelly36', 'jelly49', 'jelly64', 'jelly81', 'jelly100']

此处,[x*x for x in range(1,11)]]会提供您在字符串中使用的[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

有关OP代码行为的更多解释(由于precedence运算符*%),请查看Juanpa's answer