我有以下4个列表:
import numpy as np
file1 = np.arange(0, 4).tolist()
file2 = np.arange(3, 7).tolist()
file3 = np.arange(7, 11).tolist()
file4 = np.arange(11, 15).tolist()
,我想从每个列表中通过旋转选择,并以最终集合结束,如下所示:
final = {0, 4, 9, 14}
我有一个解决方案,但我想知道如果有一个更简单的方法或更预言的方法?
def get_rotated(file1: list,
file2: list,
file3: list,
file4: list):
count = 0
i = 0
final = set()
while i < (get_len(file1) -1):
print('here')
if count == 0:
print(i)
tag = file1[i]
count+=1
final.add(tag)
i += 1
if count == 1:
print(i)
tag = file2[i]
count+=1
final.add(tag)
i += 1
if count == 2:
print(i)
tag = file3[i]
count+=1
final.add(tag)
i += 1
if count == 3:
print(i)
tag = file4[i]
count=0
final.add(tag)
i += 1
return final
返回正确的集合{0,4,9,14}。如果列表的大小比较大,我想让它保持分组旋转。
您可以创建一个列表的列表,并选择与每个列表在列表的列表中的位置相对应的项:
[ L[i] for i,L in enumerate([file1,file2,file3,file4]) ]
[0, 4, 9, 14]
多个周期:(旋转)
如果你有更长的列表,你可以将列表列表放在一个变量中,并通过将列表列表乘以循环次数(完整旋转)来使其循环不止一个周期:
file1 = list(range(0, 14))
file2 = list(range(3, 17))
file3 = list(range(7, 21))
file4 = list(range(11, 25))
files = [file1,file2,file3,file4]
cycles = min(map(len,files))//len(files)
r = [ L[i] for i,L in enumerate(files*cycles) ]
print(r)
[0, 4, 9, 14, 4, 8, 13, 18, 8, 12, 17, 22]
作为集合:
r = { L[i] for i,L in enumerate(files*rotations) }
print(r)
{0, 4, 8, 9, 12, 13, 14, 17, 18, 22}
多个旋转(包括部分旋转)
如果需要允许序列末尾的部分旋转,可以对zip()生成的元组使用模索引:
files = [file1,file2,file3,file4]
r = [T[i%len(files)] for i,T in enumerate(zip(*files))]
print(r)
[0, 4, 9, 14, 4, 8, 13, 18, 8, 12, 17, 22, 12, 16]
这将从file1和file2中选择另外两个项:
partial
|--------|
file1: [0] 1 2 3 [4] 5 6 7 [8] 9 10 11 [12] 13
file2: 3 [4] 5 6 7 [8] 9 10 11 [12] 13 14 15 [16]
file3: 7 8 [9] 10 11 12 [13] 14 15 16 [17] 18 19 20
file4: 11 12 13 [14] 15 16 17 [18] 19 20 21 [22] 23 24
作为一组:
r = {T[i%len(files)] for i,T in enumerate(zip(*files))}
print(r)
{0, 4, 8, 9, 12, 13, 14, 16, 17, 18, 22}
如果你的输入是由迭代器组成的(例如实际的文件),这个zip()方法也可以工作,因为它不会对数据本身使用任何索引。它还使使用enumerate()的第二个参数来偏移旋转变得容易。
一个更"Pythonic"功能:
完整的函数可以看起来更"python化"。这样的:
def get_rotated(*files):
return { T[i%len(files)] for i,T in enumerate(zip(*files)) }
由于您的输出将是一个集合,您可以使用嵌套推导式来简化它,该推导式将每个列表的跨行下标偏移1(考虑到值的顺序无关紧要):
def get_rotated(*files):
return {n for i,f in enumerate(files) for n in f[i::len(files)]}
或(仅适用于4个列表):
def get_rotated(file1,file2,file3,file4):
return {*file1[::4], *file2[1::4], *file3[2::4], *file4[3::4]}
这就是你需要的。你应该像下面这样通过迭代
来使用列表名import numpy as np
file1 = np.arange(0, 4).tolist()
file2 = np.arange(3, 7).tolist()
file3 = np.arange(7, 11).tolist()
file4 = np.arange(11, 15).tolist()
countOfLists = 4
finalList = []
for i in range(1, countOfLists + 1):
finalList.append(globals()['file%s'%i][i - 1])
print(finalList)