我有一个平铺的数字列表,逻辑上是的,一组3个,其中每个三元组是(数字,\u忽略,标志[0或1]),例如:
[7,56,1, 8,0,0, 2,0,0, 6,1,1, 7,2,0, 2,99,1]
我想(pythonically)处理这个列表,根据'flag'的值创建一个新的数字列表:如果'flag'是1,那么我想要'number',否则是0。因此,上面的列表将变成:
[7, 0, 0, 6, 0, 2]
我最初的尝试是:
list = [7,56,1, 8,0,0, 2,0,0, 6,1,1, 7,2,0, 2,99,1]
numbers = list[::3]
flags = list[2::3]
result = []
for i,number in enumerate(numbers):
result.append(number if flags[i] == 1 else 0)
这是可行的,但在我看来,应该有更好的方法从列表中清晰地提取元组。比如:
list = [7,56,1, 8,0,0, 2,0,0, 6,1,1, 7,2,0, 2,99,1]
for (number, __, flag) in list:
...etc
但我好像做不到。你知道吗
我可以循环浏览整个列表:
result = []
for i in range(0, len(list), 3):
result.append(list[i] if list[i+2] == 1 else 0)
看起来更小更有效。你知道吗
我不清楚这里的最佳选择。如有任何建议,将不胜感激。你知道吗
注意:我接受了wim的回答:
[L[i]*L[i+2] for i in range(0, len(L), 3)]
但我想重申的是,wims和暗影突击队的反应都是有效的。我接受wim的答案是基于简单和清晰(以及与python2的兼容性,尽管ShadowRanger指出zip也在Py2中,所以这个基础是无效的)。你知道吗
暗影游侠的回答是:
[number if flag else 0 for number, _, flag in zip(*[iter(mylist)]*3)]
也确实做了我认为我想要的(提供元组),但有点晦涩,需要zip。正如wim所指出的,ShadowRanger的答案非常适合于数据流而不是固定的列表。你知道吗
我还要注意的是ShadowRanger的答案增加了zip()的模糊用法(随着时间的推移,它会变得不那么模糊),但是通过使用元组的命名值来增加清晰度,所以这有点胜负。你知道吗
对于那些努力理解zip(*[iter(mylist)]*3)]
的人来说,它创建了一个迭代器的三个副本,然后用来构造元组。因为它是同一个迭代器,所以每次使用都会推进迭代器,使元组完全符合我的要求。你知道吗
为了清楚和通用,我也有点倾向于@ShadowRanger的解决方案的修改版本:
i = iter(mylist)
[number if flag else 0 for number, _, flag in zip(i, i, i)]
(在我看来,这似乎不那么晦涩)。你知道吗
因为您有逻辑三元组,所以可以使用
iter
、序列乘法和zip
来实现您的目标:它将
mylist
上的相同的迭代器解压为zip
的三个参数;因为它是同一个迭代器,zip
将元素0、1和2解压为第一个输出,然后3、4和5等等。然后循环将这三个元素解压为逻辑名称(使用_
表示您不关心的值)。你知道吗列表理解甚至可以是一行:
虽然这有点复杂,意思是明智的。你知道吗
这种方法的优点是:
list
缺点:
zip(*[iter(mylist)]*3)
有点神奇注意:在任何类似于生产代码的代码中,不要内联} recipe from the ^{} module (或基于
zip
/iter
/unpack技巧。使用the ^{zip
的变体)并调用:配方是经过测试和预测的,通过给它起一个名字,你可以让使用它的代码更加明显。你知道吗
我认为最直接的方法是简单的列表理解:
或者考虑numpy,它对于这样的任务非常强大:
我想这可能有用:
相关问题 更多 >
编程相关推荐