簡體   English   中英

pythonic方法篩選具有唯一長度的元素的列表

[英]pythonic way to filter list for elements with unique length

我想過濾一個列表,只留下具有唯一長度的第一個元素。 我為它編寫了一個函數,但我相信應該有一個更簡單的方法:

def uniq_len(_list):
    from itertools import groupby
    uniq_lens = list(set([x for x, g in groupby(_list, len)]))
    all_goods = []
    for elem in _list:
        elem_len = len(elem)
        try:
            good = uniq_lens.pop([i for i, x in enumerate(uniq_lens) if x==elem_len][0])
            if good:
                all_goods.append(elem)
        except IndexError as _e:
            #print all_goods
            pass
    return all_goods

In [97]: jones
Out[97]: ['bob', 'james', 'jim', 'jon', 'bill', 'susie', 'jamie']

In [98]: uniq_len(jones)
Out[98]: ['bob', 'james', 'bill']

如果你只想按任意順序為每個長度任意字符串,那么最簡單的方法是首先轉換為dict將長度映射到字符串,然后只讀取值:

>>> {len(s): s for s in jones}.values()
dict_values(['jon', 'bill', 'jamie'])

如果你想要每個長度的一個,並且你需要保留順序,那么這只是來自itertools配方的 unique_everseen ,以len為關鍵:

>>> from more_itertools import unique_everseen
>>> list(unique_everseen(lst, key=len))
['bob', 'james', 'bill']

(如果你pip install more-itertools ,它包含了itertools文檔中的所有配方,以及一些其他有用的東西。)

獲取列表中具有唯一長度的第一項(不一定與列表中顯示的順序相同)。

>>> lst = ['bob', 'james', 'jim', 'jon', 'bill', 'susie', 'jamie']
>>> list({len(x): x for x in reversed(lst)}.values())
['bob', 'bill', 'james']

尊重原始列表的順序,您可以使用輔助集:

>>> seen = set()
>>> [x for x in lst if len(x) not in seen and seen.add(len(x)) is None]
['bob', 'james', 'bill']

對於上面的表達式連續正常工作,你必須確保你復位seen每次空集。

一個不太優雅的方式是:

>>> mylist = ['bob', 'james', 'jim', 'jon', 'bill', 'susie', 'jamie']
>>> filtered = []
>>> [filtered.append(x) for x in mylist if len(x) not in [len(y) for y in filtered]]
[None, None, None]
>>> print(filtered)
['bob', 'james', 'bill']

正如您所看到的,解釋器打印[None, None, None]因為我們appendfiltered實際上會生成一個None值列表( append方法總是返回None),然后將其丟棄。 但該行具有使用正確值填充filtered的副作用。

簡單的方法,只使用內置插件:

reduce(
         lambda o1, o2: o1 if o1 and len(o1[-1]) == len(o2) else o1 + [o2], 
         sorted(
                  orig, 
                  key=lambda o: len(o)
         ), 
         []
)

這將給你O(n * log(n))復雜度。

由於sorted是穩定的,等長字符串之間的順序將與排序之前的順序相同。 然后reduce函數將只留下每個長度的第一次出現。

列表推導是使代碼更加pythonic的好方法。 以下是對它們如何工作的一個很好的解釋: 列表理解。

因此,如何執行上述操作的示例可能類似於:

from itertools import groupby

def filterUniqueLenghts(myList):
    lengths = {k:len(list(v)) for k,v in groupby(myList, lambda a: len(a))}
    return [e for e in myList if lengths[len(e)] == 1]

a = ['hello', 'hello', 'goodbye']
print(filterUniqueLenghts(a))

# prints ['goodbye']

暫無
暫無

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

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