簡體   English   中英

從數字和字母列表中刪除字母

[英]Removing letters from a list of both numbers and letters

在我正在嘗試編寫的函數中,用戶輸入一組數字,例如“648392”。 我把這個字符串變成這樣的列表:['6','4','8','3','9','2']。

我希望能夠對這些數字進行求和,因此我將列表中的數字轉換為整數而不是字符串。 這一切都運行良好,但我也希望用戶能夠輸入字母,然后我只是將它們從列表中刪除 - 這就是我被困住的地方。 例如,用戶輸入“6483A2”。

我無法檢查元素是否是帶有isDigit的數字,因為元素顯然必須首先是整數,並且我無法將列表中的元素轉換為整數,因為有些元素是字母...我我確定有一個簡單的解決方案,但我在python中非常糟糕,所以任何幫助都將非常感激!

您可以使用str.translate過濾掉字母:

>>> from string import letters
>>> strs = "6483A2"
>>> strs.translate(None, letters)
'64832'

沒有必要將字符串轉換為列表,您可以迭代字符串本身。

使用str.joinstr.isdigit和list comprehension:

>>> ''.join([c for c in strs if c.isdigit()])
'64832'

或者這就像你想要的數字之sum

sum(int(c) for c in strs if c.isdigit())

時間比較:

小字符串:

>>> strs = "6483A2"
>>> %timeit sum(int(c) for c in strs.translate(None, letters))
100000 loops, best of 3: 9.19 us per loop
>>> %timeit sum(int(c) for c in strs if c.isdigit())
100000 loops, best of 3: 10.1 us per loop

大字符串:

>>> strs = "6483A2"*1000
>>> %timeit sum(int(c) for c in strs.translate(None, letters))
100 loops, best of 3: 5.47 ms per loop
>>> %timeit sum(int(c) for c in strs if c.isdigit())
100 loops, best of 3: 8.54 ms per loop

最壞的情況,所有字母:

>>> strs = "A"*100
>>> %timeit sum(int(c) for c in strs.translate(None, letters))
100000 loops, best of 3: 2.53 us per loop
>>> %timeit sum(int(c) for c in strs if c.isdigit())
10000 loops, best of 3: 24.8 us per loop
>>> strs = "A"*1000
>>> %timeit sum(int(c) for c in strs.translate(None, letters))
100000 loops, best of 3: 7.34 us per loop
>>> %timeit sum(int(c) for c in strs if c.isdigit())
1000 loops, best of 3: 210 us per loop

您可以使用過濾filter函數或理解來過濾任何可迭代(包括字符串)中的內容。 例如,以下任何一個:

digits = filter(str.isdigit, input_string)
digits = (character for character in input_string if character.isdigit())

...會給你一個可迭代的數字。 如果要將每個轉換為數字,則其中任何一個都可以執行此操作:

numbers = map(int, filter(str.isdigit, input_string))
numbers = (int(character) for character in input_string if character.isdigit())

因此,要獲取所有數字的總和,跳過字母,只需將其中任何一個傳遞給sum函數:

total = sum(map(int, filter(str.isdigit, input_string)))
total = sum(int(character) for character in input_string if character.isdigit())

從你的最后一段:

我無法檢查元素是否是帶有isDigit的數字,因為元素顯然必須首先是整數,並且我無法將列表中的元素轉換為整數

首先,它是isdigit ,而不是isDigit 其次, isdigit是一個關於字符串而不是整數的方法,所以你認為你不能在字符串上調用它是錯誤的。 實際上,在將它們轉換為整數之前, 必須在字符串上調用它。

但這確實提出了另一種選擇。 在Python中, 要求寬恕通常比權限更容易 我們可以嘗試將它轉換為int,然后處理可能的失敗,而不是弄清楚我們是否可以將每個字母轉換為int,然后再進行轉換。 例如:

def get_numbers(input_string):
    for character in input_string:
        try:
            yield int(character)
        except TypeError:
            pass

現在,它只是:

total = sum(get_numbers(input_string))

你可以通過理解來做到這一點:

>>> s = "6483A2"
>>> [int(c) for c in s if c.isdigit()]
[6, 4, 8, 3, 2]
>>> sum(int(c) for c in s if c.isdigit())
23

如果你想直接從混合字符串到只有整數的列表,這種方法很好,這可能是你的目標。

您可以使用生成器表達式並將其放入sum

>>> import string
>>> s
'6483A2'
>>> sum(int(x) for x in list(s) if x in string.digits)
23

如果沒有其他模塊要導入,請使用isdigit

sum(int(x) for x in list(s) if x.isdigit())
>>> a = "hello123987io"
>>> b = "khj7djksh787"
>>> sum([int(letter) for letter in b if letter.isdigit()])
29
>>> sum([int(letter) for letter in a if letter.isdigit()])
30

>>> def getInputAndSum(userInput):
...     """ returns a tuple with the input string and its sum """
...     return userInput, sum([int(letter) for letter in userInput if letter.isdigit()])
... 
>>> getInputAndSum("Th1s1550mesum")
('Th1s1550mesum', 12)

只是貢獻一點,如果你想要匯總總和,你可以這樣做:

x = "6483A2"
sum(map(int, filter(str.isdigit, x)))
>>>23

如果您只需要用於其他目的的整數列表或其他類型的sum ,請將其保留在map

map(int, filter(str.isdigit, x))
>>>[6, 4, 8, 3, 2]

注意:關於string.letters方法。 letters依賴於locale因此:

import locale, string
locale.setlocale(locale.LC_ALL, 'es_ES') # or 'esp_esp' if you're on Windows
string.letters
>>> "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzŠŚŽšśžźŞµşŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőöřůúűüýţ˙"

雖然如上所述,我會為這種情況推薦regex :)

很高興合作:D

雖然你可以用各種方式過濾掉字母,但是讓譯員決定什么可以被解釋為數字和什么不可以。 所以即使它不是單行,你可能更喜歡這種方法:

aninput = "648392A0&sle4"
def discard_non_ints(itbl, rdx=10):
  for d in itbl:
    try:
      yield(int(d, rdx))
    except ValueError:
      pass

sum(discard_non_ints(aninput))
36

這種方法特別好用的是它可以靈活地包含非十進制數字。 想要求所有十六進制數字?

sum(discard_non_ints('deadbeforenoon', 16))
104

暫無
暫無

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

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