我有以下串列:
a = [ 1, 6, 76, 15, 46, 55, 47, 15, 72, 58, ..] # there could be more than 10 elements in each
b = [17, 48, 22, 7, 35, 19, 91, 85, 49, 35, ..]
c = [46, 8, 53, 49, 28, 82, 30, 86, 57, 9, ..]
d = [82, 12, 24, 60, 66, 17, 13, 69, 28, 99, ..]
e = [ 1, 53, 17, 82, 21, 20, 88, 10, 82, 41, ..]
我想要寫一個函式,它接受任何數量的這些串列的(可能是所有,可能是唯一的a,并c例如)作為它的引數和選擇從每個串列中最左邊的獨特的10個元素相等。例如,我將在圖片中顯示。
我們擁有的初始資料(假設長度為 10)。

我們查看每一行的第一個元素,看到a并e具有相同的值。我們隨機選擇比方說e,洗掉該元素并將其向左移動并得到這個

在這里我們看到再次重疊,17 已經出現,我們再移動e一次

再次出現類似問題,我們最后一次將其轉移

最后,我們可以選擇每個串列的前兩個元素,不會有重復
[1, 6, 17, 48, 46, 8, 82, 12, 21, 53]
可能有多個串列具有相同的值,應該應用相同的規則。
我帶著這個來解決隨機性問題,我決定在使用它之前洗牌:
def prepare_unique_array(
arrays: list = [],
max_length: int = 10,
slice_number: int = 2
):
unique_array = []
for array in arrays:
for i in range(slice_number):
while not len(unique_array) == max_length:
if array[i] not in unique_array:
unique_array.append(array[i])
else:
while array[i 1] in unique_array:
i = 1
unique_array.append(array[i 1])
return unique_array
在給定這些初始值的情況下,這給出了所需的結果,但任何改變都不起作用。
也許有一種 numpy 方法可以更快更容易地完成它。
我將不勝感激任何指南/幫助
uj5u.com熱心網友回復:
交替使用cycle和iter從每個可迭代物件中選擇一個元素:
from itertools import cycle
def uniques_evenly(n, *iterables):
its = cycle(iter(seq) for seq in iterables)
seen = set()
it = next(its)
for _ in range(n):
x = next(it)
while x in seen:
x = next(it) # pick next unique number
seen.add(x)
yield x
it = next(its) # switch to next iterator
請注意,如果迭代器之一太短,這將崩潰。
測驗:
a = [ 1, 6, 76, 15, 46, 55, 47, 15, 72, 58, 37756, 712, 666]
b = [17, 48, 22, 7, 35, 19, 91, 85, 49, 35, 42]
c = [46, 8, 53, 49, 28, 82, 30, 86, 57, 9]
d = [82, 12, 24, 60, 66, 17, 13, 69, 28, 99]
e = [ 1, 53, 17, 82, 21, 20, 88, 10, 82, 41, 216]
print( list(uniques_evenly(10, a,b,c,d,e)) )
# [1, 17, 46, 82, 53, 6, 48, 8, 12, 21]
說明
我們iter()用來將串列轉換為迭代器。迭代器是在每次呼叫next(). 例如:
l = [3, 4, 7] # l is a list
i = iter(l) # i is an iterator
print( next(i) )
# 3
print( next(i) )
# 4
print( next(i) )
# 7
print( next(i) )
# raises exception StopIteration
然后,我們使用itertools.cycle在五個迭代器之間交替。cycle回傳一個無限迭代器,它在我們給它的串列中的專案之間回圈。我們給了它一個包含五個迭代器的串列:
its = cycle(iter(seq) for seq in iterables)
這就像我們寫的一樣:
its = cycle([iter(a), iter(b), iter(c), iter(d), iter(e)]
這是一個只有兩個迭代器而不是 5 個迭代器的演示:
a = ['hello', 'world']
b = [5, 12]
its = cycle([iter(a), iter(b)])
it = next(its) # it is now the iterator on a
print( next(it) ) # 'hello'
it = next(its) # it is now the iterator on b
print( next(it) ) # 5
it = next(its) # it cycles back to a
print( next(it) ) # 'world'
it = next(its) # it is now b
print( next(it) ) # 12
it = next(its) # it is a
print( next(it) ) # raises exception StopIteration
所以這基本上就是uniques_evenly.
另外,我們使用一個集合seen來記住我們已經看到的元素。集合很酷,因為測驗成員資格是一個快速的操作:if x in seen:是一個恒定時間的操作,不管有多大seen。
Nowit是五個迭代器之一,比如 list 上的迭代器d。我們挑選下一個元素中d有x = next(it); 然后我們運行回圈:
while x in seen:
x = next(it)
這意味著:如果x是之前已經見過的元素,則選擇 中的下一個元素d。繼續選擇下一個元素,直到找到以前未見過的元素。一旦我們最終選擇了一個x以前沒有見過的元素,我們將它添加到 setseen以便將來不會再次選擇它,然后:
yield x
This is a bit special. It means uniques_evenly is not a function; if it was a function, we would have used the keyword return and not yield. Instead, uniques_evenly is a generator. Instead of using this syntax with yield, the other alternative would have been to declare a list result, initially empty, then instead of yield x, I would have written result.append(x); then at the very end of the function, return result. Then uniques_evenly would have been a function that returns a list.
The difference between a function that returns a list, and a generator, is a bit subtle. Basically a generator behaves like a lazy list, whose elements are computed and produced only when needed.
When testing my code, I immediately converted the generator to a list anyway:
print( list(uniques_evenly(10, a,b,c,d,e)) )
所以區別并不重要。如果您更喜歡擁有一個變數result并使用result.append(x)而不是yield x,然后result在函式的末尾回傳,那么您可以這樣做。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/377846.html
上一篇:獲取每個節點的最大樹深度
下一篇:使用二進制操作的反向解密演算法
