簡體   English   中英

獲取兩個列表相交的項目索引的Python方法

[英]Pythonic way to get index of items where two list intersect

說我有兩個列表:一個是字符串-'example',另一個是字母。 我想找到一種更Python化的方式,其中字母列表中每個位置的字符串列表“ example”的每個字母都相交並將這些索引放在列表中。 IE

  • e:4
  • x:23
  • a:0
  • 米:12

等等...

到目前為止,我有:

import string
alphabet = list(string.ascii_lowercase)
key = list('example')

def convert(string, alphabet):
    table_l = []
    for char in string:
        for letter in alphabet:
            if letter == char:
                table_l.append(alphabet.index(letter))
    return table_l

convert(key, alphabet)

我嘗試使用集合交集,但是字符串'key'可以包含每個字母中的多個,而且我正在尋找索引,而不是匹配的字母。

到目前為止,我嘗試過的最好的方法是:

for x in key:
    listed.append(set(alphabet).intersection(x))

我不知道如何在值與每個鍵字母相交的地方附加字母鍵。

謝謝

你想從字母到數字的映射 ,所以使用映射數據結構,例如dict

>>> alphamap = dict(zip(alphabet, range(len(alphabet)))
>>> alphamap
{'h': 7, 'e': 4, 'g': 6, 'n': 13, 'm': 12, 's': 18, 'x': 23, 'r': 17, 'o': 14, 'f': 5, 'a': 0, 'v': 21, 't': 19, 'd': 3, 'j': 9, 'l': 11, 'b': 1, 'u': 20, 'y': 24, 'q': 16, 'k': 10, 'c': 2, 'w': 22, 'p': 15, 'i': 8, 'z': 25}
>>> def convert(string, map_):
...     return  [map_[c] for c in string]
...
>>> convert('example', alphamap)
[4, 23, 0, 12, 15, 11, 4]

注意,您的原始方法可以簡化為:

>>> list(map(alphabet.index, 'example'))
[4, 23, 0, 12, 15, 11, 4]

但是,使用alphabet.index比使用映射效率低(因為它每次都必須進行線性搜索而不是固定時間的哈希)。

另外,請注意,我直接遍歷了字符串,不需要將它們放入列表中, 字符串就像list對象一樣是序列 可以對其進行迭代,切片等。但是,它們是不可變的。

最后,如果沒有相應的值(即特殊的非字母字符),上述方法將失敗。

>>> convert("example!", alphamap)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in convert
  File "<stdin>", line 2, in <listcomp>
KeyError: '!'

這可能是理想的,也可能不是理想的。 另外,您可以通過將.get與默認值一起使用來解決此問題,例如:

>>> def convert(string, map_, default=-1):
...     return  [map_.get(c, default) for c in string]
...
>>> convert("example!", alphamap)
[4, 23, 0, 12, 15, 11, 4, -1]

如果全部為ascii,則應執行以下操作-將字母轉換為數字表示形式,然后減去97,因為這是ascii中的“ a”

a = ord(‘a’)
[ord(c)-a for c in ‘example’.lower()]

以與Guy相同的精神,以36為底數(並遵循DyZ和mhawke的建議),

>>> a = int('a', 36)
>>> [int(c, 36) - a for c in 'example']
[4, 23, 0, 12, 15, 11, 4]


請注意,此方法不區分大小寫,並且如果全部為ascii,則可以使用(自從您使用string.ascii_lowercase播放以來,情況就是string.ascii_lowercase )。

使用集。

overlapKeys = set(alphabet) & set(key)
listOfIndices = [alphabet.index(key) for key in overlapKeys]

也,

key = list('example')

是不必要的。 字符串是字符列表。 采用

key = 'example'

您的示例似乎有點不對…… x不會是23, m 12等嗎?

>>> s = 'example'
>>> [(c, string.ascii_lowercase.index(c)) for c in s]    # as a list of tuples
[('e', 4), ('x', 23), ('a', 0), ('m', 12), ('p', 15), ('l', 11), ('e', 4)]

對於較長的字符串,這會有些效率低下,因為使用index()有效地使其成為O(n ** 2)解決方案。

更好的方法是使用查找字典將字符轉換為其索引。 由於dict查找為O(1),因此得出的結果將是O(n),這要好得多。

# create a dict that maps characters to indices
indices = {c: index for index, c in enumerate(string.ascii_lowercase)}
# perform the conversion
>>> s = 'example'
>>> [(c, indices.get(c, -1)) for c in s]
[('e', 4), ('x', 23), ('a', 0), ('m', 12), ('p', 15), ('l', 11), ('e', 4)]

如果只需要索引:

>>> [indices.get(c, -1) for c in s]
[4, 23, 0, 12, 15, 11, 4]

暫無
暫無

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

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