我有一些包含加性逆對的串列(添加兩個對會給你零),對于每個串列,我試圖洗掉這些對。
下面是一些例子,我試圖從這里開始:
lst1 = [326, -326, 336, -336, 336]
lst2 = [-35, 35, 838, -838, 440]
lst3 = [544, -544, 544]
lst4 = [-25, 25, 32, -32, -32, 56, 79]
對此:
lst1 = [336]
lst2 = [440]
lst3 = [544]
lst4 = [-32, 56, 79]
您可以看到,在每個串列中,加法逆對被洗掉,留下沒有加逆的值,或 1 個額外的非鏡像值。
我希望我能分享我嘗試過的東西,但我已經研究了幾天,我想出的任何邏輯都與lst4.
我似乎找到了一個解決方案,它產生了我需要的東西,但是它是用 R 撰寫的,我沒有經驗,所以我無法理解邏輯。
關于如何克服這個問題的任何想法?
uj5u.com熱心網友回復:
您可以跟蹤您在(默認)字典檔案中看到的所有元素
字典是一種保存鍵值對并允許快速查找的資料結構。在這種情況下,我們輸入串列的元素將是我們的鍵,而值將是一個計數。您訪問值在字典中,像這樣:counter[key] = value。
一個默認的字典只是讓這樣,當key尚未字典的一部分,它會自動生成它的默認值,而不是扔的KeyError。所以我們定義counter = collections.defaultdict(int). 在int指定為尚未未定義鍵的值默認出廠功能。
每次看到未配對的數字時,都會增加該數字的計數器。每次您在計數器中找到一個有一對的數字時,您就減少該對的計數器。最后,計數器的鍵將是串列的元素,值將是找到的該元素的未配對實體的數量,因此我們根據需要將其轉換為串列。請注意,這不會保留原始串列中元素的順序。
import collections
def filterInverse(lst):
counter = collections.defaultdict(int)
for num in lst:
inverse = -num
if counter[inverse] > 0:
# Inverse was found previously in the counter
# Decrement counter[inverse]
counter[inverse] -= 1
# And do nothing else with this number
else: # Inverse wasn't found in the counter
# This is an unpaired number so add it to the counter
counter[num] = 1
# Finally, go over the dict and return the keys whose values are nonzero
# Repeat each item by its count
# print(counter)
rv = []
for num, ct in counter.items():
for _ in range(ct):
rv.append(num)
return rv
使用您問題中的輸入以及我們在評論中討論的內容運行此程式,
>>> filterInverse(lst1)
Out: [336]
>>> filterInverse(lst2)
Out: [440]
>>> filterInverse(lst3)
Out: [544]
>>> filterInverse(lst4)
Out: [-32, 56, 79]
>>> lst5 = [-1, 0, 1, -1, -1]
>>> filterInverse(lst5)
Out: [-1, -1, 0]
如果您堅決反對使用defaultdict,則可以通過使用常規dict.get(key, default)檔案獲得相同的行為:
counter = dict()
...
...
if counter.get(inverse, 0) > 0:
# Inverse was found previously in the counter
# Decrement counter[inverse]
counter[inverse] = counter.get(inverse, 0) - 1
# And do nothing else with this number
else: # Inverse wasn't found in the counter
# This is an unpaired number so add it to the counter
counter[num] = counter.get(num, 0) 1
...
...
uj5u.com熱心網友回復:
您可以使用defaultdict跟蹤加法對以及處理重復項:
from collections import defaultdict
from itertools import chain
def remove_additive_pairs(sequence: list) -> list:
""" Remove additive pairs from given sequence. """
result = defaultdict(list)
for element in sequence:
if -element in result:
del result[-element]
else:
result[element].append(element)
return list(chain.from_iterable(result.values()))
>>> lst5 = [-25, 25, 32, -25, 25, 32]
>>> for seq in [lst1, lst2, lst3, lst4, lst5]:
print(remove_additive_pairs(seq))
[336]
[440]
[544]
[-32, 56, 79]
[32, 32]
當然,您可以在不匯入itertools.chain或的情況下執行相同操作collections.defaultdict:
def chain(args):
for lst in args:
for elem in lst:
yield elem
def remove_additive_pairs(sequence: list) -> list:
""" Remove additive pairs from given sequence. """
result = dict()
for element in sequence:
if -element in result:
del result[-element]
else:
result.setdefault(element, []).append(element)
return list(chain(result.values()))
defaultdict是一個dict-like可以為 提供default值的容器missing keys。例如:
>>> d = defaultdict(list)
>>> d[5]
[]
因此,定義defaultdict(list)可確保當我們得到一個其逆不在鍵中的數字時,我們可以將該數字作為 a 添加key到字典中,并一步將append其添加到list其值中的a中。
uj5u.com熱心網友回復:
首先,計算每個值在串列中出現的次數。然后遍歷串列,填充一個新串列或丟棄該值并遞減反向值的計數器。
from collections import Counter
def remove_inverses(lst):
value_counts = Counter(lst)
result = []
for element in lst:
if value_counts.get(-element):
value_counts[-element] -= 1
else:
result.append(element)
return result
uj5u.com熱心網友回復:
使用真棒collections.Counter:
from collections import Counter
from itertools import repeat
def remove_opposite_pairs(seq):
dplus = Counter(seq)
dminus = Counter(-x for x in seq)
for x,n in (dplus - dminus).items():
yield from repeat(x, n)
lsts = [[326, -326, 336, -336, 336],
[-35, 35, 838, -838, 440],
[544, -544, 544],
[-25, 25, 32, -32, -32, 56, 79],
[-1, 0, 1, -1, -1]]
for l in lsts:
print(list(remove_opposite_pairs(l)))
# [336]
# [440]
# [544]
# [-32, 56, 79]
# [-1, -1]
注意 0 上的奇怪行為,因為 0 是它自己的對立面。我可以解決它,但首先您需要編輯您的問題以準確指定如何處理 0。
這是一個可能的修復方法:
from collections import Counter
from itertools import repeat
def remove_opposite_pairs(seq):
dplus = Counter(seq)
dminus = Counter(-x for x in seq)
for x,n in (dplus - dminus).items():
yield from repeat(x, n)
if dplus[0] % 2 == 1:
yield 0
lsts = [[-1, 0, 1, -1, -1],
[0, 0],
[0, 0, 0]]
for l in lsts:
print(list(remove_opposite_pairs(l)))
# [-1, -1, 0]
# []
# [0]
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/362856.html
上一篇:以演算法方式執行浮點加法
