簡體   English   中英

基於每個元組中存在的元素在列表中查找互斥元組的優雅方式

[英]Elegant way to find mutually exclusive tuples in the list based on the element present in each tuple

我想從彼此中減去以下兩個元組以獲得所需的結果(也包含在下面)。 請注意,減法僅基於(a,b)中的a。

# the two tuples
first = [(('the',), 431), (('and',), 367)]
second = [(('the',), 100), (('hello',), 100)]

# the desired result
first = [(('and',), 367)]
second = [(('hello',), 100)]

我試過map(operation.sub, first, second) ,沒用。 試過b = map(sub, first, second) ,沒用。 表示不支持的操作數類型 - :'tuple'和'tuple

感謝您的幫助和提前的時間。

編輯 :最能幫助我的解決方案包括創建兩個元組的交集並從每個元組中減去它。

編輯:我想基於常見項目減去。 希望澄清一下。

這是你在找什么 -

# the two tuples
first = [(('the',), 431), (('and',), 367)]
second = [(('the',), 100), (('hello',), 100)]

interim1 = {i[0][0]:i[1] for i in first}

interim2 = {i[0][0]:i[1] for i in second}

op1 = [ ((item,),interim1[item]) for item in interim1 if item not in interim2]
op2 = [ ((item,),interim2[item]) for item in interim2 if item not in interim1]
print(op1)
print(op2)

交叉點(編輯)

intersection = [ ((item,),interim1[item]) for item in interim1 if item in interim2]
print(intersection)

聯盟(額外)

union = set().union(*[ op1, op2, intersection])
print(union)

產量

[(('the',), 431)]
[(('and',), 367)]
[(('hello',), 100)]
{(('hello',), 100), (('and',), 367), (('the',), 431)}

您可以使用帶有以下列表理解的 set來獲得所需的結果:

>>> first = [(('the',), 431), (('and',), 367)]
>>> second = [(('the',), 100), (('hello',), 100)]

>>> [t for t in first+second if t[0] in set(f[0] for f in first) ^ (set(s[0] for s in second))]
[(('and',), 367), (('hello',), 100)]

說明:

在這里,我使用set通過在兩個集合上執行XOR(也稱為異或)來獲取兩個列表中的非公共單詞。 例如:

>>> first_words = set(f[0] for f in first)
>>> second_words = set(s[0] for s in second)

>>> first_words ^ second_words
set([('hello',), ('and',)])

然后,我在列表理解中的列表上進行迭代,並檢查它們是否存在於上面的非常用單詞元組中。 如果它們存在,那么我們將它作為新列表的一部分保存為:

>>> result = [t for t in first+second if t[0] in first_words ^ second_words]
# where `result` will hold value `[(('and',), 367), (('hello',), 100)]`

## If your resultant lists contains only two variable, 
## then you may assign them directly to individual variable as:
#     f, s = [t for t in first+second if t[0] in first_words ^ second_words]

## where `f` first required tuple will hold
# >>> f
# (('and',), 367)

## and `s` second required tuple will hold
# >>> s
# (('hello',), 100)

也許以下就是你想要的:

# the two tuples
first = [(('the',), 431), (('and',), 367)]
second = [(('the',), 100), (('hello',), 100)]

first_keys = set(_[0][0] for _ in first)
second_keys = set(_[0][0] for _ in second)

first = [_ for _ in first if _[0][0] not in second_keys]
second = [_ for _ in second if _[0][0] not in first_keys]

multi = [
    [(('the',), 431), (('and',), 367)],
    [(('the',), 100), (('hello',), 100)]
]

def get_key(x):
    return x[0][0]

def occur_counts(set_x):
    cnt = {}
    for x in set_x:
        cnt[get_key(x)] = cnt.get(get_key(x), 0) + 1
    return cnt


def do_one(single, total_cnt):
    single_cnt = occur_counts(single)
    return [_ for _ in single if single_cnt[get_key(_)] == total_cnt[get_key(_)]]


total_cnt = occur_counts(sum(multi, []))

answer = [do_one(_, total_cnt) for _ in multi]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM