我有一个列表:[1,2,3,4,5,6,0,9,2]
我想循环播放。
我希望为每3个元素创建另一个字典列表,直到我到达0
元素(即第一个字典为{'gold':1,'silver':2,'bronze':3}
,类似于4,5,6
)。循环将终止,因为它达到0
。
结果列表如下:[{'gold':1,'silver':2,'bronze':3},{'gold':4,'silver':5,'bronze':6}]
作为Python的新手并且来自PHP背景,我如何解决像zip
或map
这样的杠杆函数,或者我必须求助于简单的while循环?
答案 0 :(得分:4)
from itertools import cycle
placings = cycle(['gold', 'silver', 'bronze'])
numbers = [1,2,3,4,5,6,0,9,2]
def zipper(numbers, placings):
d = {}
for n, c in zip(numbers, placings):
if n == 0:
break
d[n] = c
if n % 3 == 0:
yield d
d = {}
print list(zipper(numbers, placings))
答案 1 :(得分:2)
#block {
width: 100%;
height: 200px;
background-color: red;
}
只要谓词为真,就创建一个从迭代中返回元素的迭代器。
因此,我们只将元素提取到我们遇到的第一个from itertools import takewhile, islice
def groups(l, keys, i, n):
# lambda x: x != 0 -> take elements until we encounter any 0
tk = takewhile(lambda x: x != i, l)
while True:
d = dict(zip(keys, islice(tk, n)))
if len(d) == n: # make sure we have n keys in the dict
yield d
else:
break
keys = ['gold', 'silver', 'bronze']
print(list(groups(l,keys,0,3)))
[{'bronze': 3, 'gold': 1, 'silver': 2}, {'bronze': 6, 'gold': 4, 'silver': 5}]
,i
使用islice从我们的takewhile对象获取d = islice(tk,n)
长度切片,然后我们创建一个dict从传入的键中,创建dict一次消耗n
个元素,因此每次调用它时我们都会移动到接下来的三个元素。如果takewhile对象的长度不是n
的倍数,那么我们将在末尾有一个小于n
大小的dict,因此n
将捕获并突破循环所以奇数长度dict或空dict将终止while。
如果您允许少于三个键的词组:
if len(d) == n:
输出:
from itertools import takewhile, islice,chain
def groups(l, keys, i, n):
tk = takewhile(lambda x: x != i, l)
return (dict(zip(keys, chain(islice(tk, n - 1),(i,)))) for i in tk)
In [5]: l = [1, 2, 3, 4, 5, 6, 7, 11, 6, 9, 0, 2]
In [6]: list(groups(l,['gold', 'silver', 'bronze'],0,3))
Out[6]:
[{'bronze': 1, 'gold': 2, 'silver': 3},
{'bronze': 4, 'gold': 5, 'silver': 6},
{'bronze': 7, 'gold': 11, 'silver': 6},
{'gold': 9}]
从我们的takewhile对象len n - 1中获取一个切片,我们将其链接到islice(tk, n - 1)
,因此每次都会得到i
个元素。
或者使用过滤器以少于3个键过滤掉dict:
n
删除较短的字典:
def groups(l, keys, i, n):
tk = takewhile(lambda x: x != i, l)
return filter(lambda x: len(x) == n, (dict(zip(keys, chain(islice(tk, n - 1),(i,))))
for i in tk))
这与前一个相同,我们只是从末尾过滤任何潜在的奇数长度dict。对于python2,请使用In [8]: list(groups(l,['gold', 'silver', 'bronze'],0,3))
Out[8]:
[{'bronze': 1, 'gold': 2, 'silver': 3},
{'bronze': 4, 'gold': 5, 'silver': 6},
{'bronze': 7, 'gold': 11, 'silver': 6}]
而不是过滤器。
答案 2 :(得分:1)
轻松!使用简单的函数,数据结构和简单的迭代:
示例:强>
from collections import defaultdict
def f(xs, labels=("gold", "silver", "bronze")):
d = defaultdict(int)
n = 0
for i, x in enumerate(xs):
if x == 0: # break if we see a 0
return d
d[labels[n]] += i # update our counts
# cycle through gold/silver/bronze (labels)
n += 1
if n % 3 == 0:
n = 0
return d
xs = [1, 2, 3, 4, 5, 6, 0, 9, 2]
d = f(xs)
print d
<强>输出:强>
$ python foo.py
defaultdict(<type 'int'>, {'bronze': 7, 'silver': 5, 'gold': 3})
答案 3 :(得分:1)
首先,您需要将较大的列表拆分为与列表medals
相同大小的较小列表,以使zip()
函数正常工作,同时0
的位置也可以列表应该在medals
列表的长度可以被整除的位置,否则较小列表中的最后一个列表将具有较少数量的元素。
listOfDictionary = []
lst = [1,2,3,4,5,6,0,9,2]
ind = lst.index(0) #Tells where to break the iteration loop.
medals = ["gold", "silver", "bronze"]
if ind%3==0:
newlst = [lst[i: i+3]for i in xrange(0,ind,3)]
#newlst = [[1, 2, 3], [4, 5, 6]]
for lsst in newlst:
listOfDictionary.append(dict(zip(medals, lsst)))
print listOfDictionary
>>> [{'bronze': 3, 'silver': 2, 'gold': 1}, {'bronze': 6, 'silver': 5, 'gold': 4}]
答案 4 :(得分:1)
在列表的情况下使用列表理解,然后使用循环
In [61]: mykeys
Out[61]: [1, 2, 3, 4, 5, 6, 0, 9, 2]
In [63]: mykeys1=[i for i in mykeys[:-1 if 0 not in mykeys else mykeys.index(0)]]
In [64]: myvalues
Out[64]: ['gold', 'silver', 'bronze']
In [66]: myvalues1=cycle(myvalues)
In [67]: mydict=dict(zip(mykeys1,myvalues1))
In [68]: mydict
Out[68]: {1: 'gold', 2: 'silver', 3: 'bronze', 4: 'gold', 5: 'silver', 6: 'bronze'}
In [69]: [dict(mydict.items()[i:i+3]) for i in range(0,len(mykeys1),3)]
Out[69]: [{1: 'gold', 2: 'silver', 3: 'bronze'}, {4: 'gold', 5: 'silver', 6: 'bronze'}]