पायथन का उपयोग करके स्ट्रिंग से अंकों को छोड़कर वर्ण निकालें?


137

मैं स्ट्रिंग से संख्याओं को छोड़कर सभी वर्णों को कैसे निकाल सकता हूं?


@ जान तंजार: क्या आप एक उदाहरण दे सकते हैं?
जोहो सिल्वा

@ जेजी: मेरे पास gtk.Entry () है और मैं चाहता हूं कि इसमें कई बार फ्लोट दर्ज किया जाए।
जन तोंजर

1
@JanTojnar उत्तर दो और स्पष्ट रूप से सूची के अनुसार re.sub पद्धति का उपयोग करता है जो उदाहरण के लिए re.sub ("[^ 0123456789 \।]", "", "Poo123.4and5fish"
रोजर हीथकोट

जवाबों:


112

पाइथन 2. * में, अब तक का सबसे तेज़ तरीका है .translate:

>>> x='aaa12333bb445bb54b5b52'
>>> import string
>>> all=string.maketrans('','')
>>> nodigs=all.translate(all, string.digits)
>>> x.translate(all, nodigs)
'1233344554552'
>>> 

string.maketransएक अनुवाद तालिका (लंबाई 256 की एक स्ट्रिंग) बनाती है, जो इस मामले में वैसी ही है ''.join(chr(x) for x in range(256))(बनाने में तेज़; ;-) .translateअनुवाद तालिका लागू करता है (जो allअनिवार्य रूप से पहचान के बाद से अप्रासंगिक है) और दूसरे तर्क में मौजूद वर्णों को हटा देता है - प्रमुख भाग।

.translateयूनिकोड स्ट्रिंग्स पर बहुत अलग तरीके से काम करता है (और पायथन 3 में तार - मैं यह निर्दिष्ट करना चाहता हूं कि पायथन का कौन सा प्रमुख रिलीज ब्याज का है!) - यह काफी सरल नहीं है, यह बहुत तेजी से नहीं, हालांकि अभी भी काफी उपयोगी है।

2. * पर वापस, प्रदर्शन अंतर प्रभावशाली है ...:

$ python -mtimeit -s'import string; all=string.maketrans("", ""); nodig=all.translate(all, string.digits); x="aaa12333bb445bb54b5b52"' 'x.translate(all, nodig)'
1000000 loops, best of 3: 1.04 usec per loop
$ python -mtimeit -s'import re;  x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loops, best of 3: 7.9 usec per loop

7-8 बार चीजों को गति देना शायद ही मूंगफली है, इसलिए translateविधि अच्छी तरह से जानने और उपयोग करने लायक है। अन्य लोकप्रिय गैर-आरई दृष्टिकोण ...:

$ python -mtimeit -s'x="aaa12333bb445bb54b5b52"' '"".join(i for i in x if i.isdigit())'
100000 loops, best of 3: 11.5 usec per loop

आरई की तुलना में 50% धीमा है, इसलिए .translateदृष्टिकोण इसे परिमाण के एक क्रम से अधिक धड़कता है।

पायथन 3 में, या यूनिकोड के लिए, आपको .translateएक मैपिंग (अध्यादेशों के साथ, वर्णों को सीधे नहीं, कुंजी के रूप में) पास करने की आवश्यकता होती है , Noneजो आप हटाना चाहते हैं। "कुछ लेकिन" कुछ वर्णों को हटाने के लिए इसे व्यक्त करने का एक सुविधाजनक तरीका है:

import string

class Del:
  def __init__(self, keep=string.digits):
    self.comp = dict((ord(c),c) for c in keep)
  def __getitem__(self, k):
    return self.comp.get(k)

DD = Del()

x='aaa12333bb445bb54b5b52'
x.translate(DD)

भी निकलता है '1233344554552'। हालाँकि, इसे xx.py में रखकर हमारे पास ...:

$ python3.1 -mtimeit -s'import re;  x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
100000 loops, best of 3: 8.43 usec per loop
$ python3.1 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)'
10000 loops, best of 3: 24.3 usec per loop

... जो दिखाता है कि प्रदर्शन लाभ गायब हो जाता है, इस तरह के "विलोपन" कार्यों के लिए, और प्रदर्शन में कमी हो जाती है।


1
@sunqiang, हाँ, बिल्कुल - वहाँ एक कारण है Py3k पाठ स्ट्रिंग प्रकार के रूप में यूनिकोड में चला गया है, बाइट के बजाय Py2 में स्ट्रिंग - एक ही कारण जावा और सी # हमेशा एक ही है "स्ट्रिंग का अर्थ है यूनिकोड" मेमे ... कुछ उपरि, शायद, लेकिन कुछ भी लेकिन अंग्रेजी के बारे में बेहतर समर्थन के लिए! -)।
एलेक्स मार्टेली

29
x.translate(None, string.digits)वास्तव में परिणाम 'aaabbbbbb', जो कि इरादा है के विपरीत है।
टॉम डेलिंग

4
टॉम डैलिंग की टिप्पणियों से गूंज, आपका पहला उदाहरण सभी अवांछनीय पात्रों को रखता है - आपने जो कहा, उसके विपरीत है।
क्रिस जॉनसन

3
@ RyanB.Lynch et al, दोष बाद के संपादक और दो अन्य उपयोगकर्ताओं के साथ था , जिन्होंने कहा था कि संपादित करें , जो वास्तव में, पूरी तरह से गलत है। वापस लाया गया।
निक टी।

1
ओवरराइडिंग allबिलिन ... इस बारे में निश्चित नहीं है!
एंडी हेडन

197

उपयोग करें re.sub, जैसे:

>>> import re
>>> re.sub('\D', '', 'aas30dsa20')
'3020'

\D किसी भी गैर-अंक चरित्र से मेल खाता है, इसलिए उपरोक्त कोड, अनिवार्य रूप से खाली स्ट्रिंग के लिए हर गैर-अंक चरित्र की जगह ले रहा है।

या आप का उपयोग कर सकते हैं filter, जैसे (अजगर 2 में):

>>> filter(str.isdigit, 'aas30dsa20')
'3020'

चूंकि पायथन 3, के filterबजाय एक पुनरावृत्ति देता है list, आप इसके बजाय निम्नलिखित का उपयोग कर सकते हैं:

>>> ''.join(filter(str.isdigit, 'aas30dsa20'))
'3020'

इस तरह के सरल कार्य में फिर से बुराई है, दूसरा जो मुझे लगता है कि सबसे अच्छा है, क्योंकि 'है ...' तरीके स्ट्रिंग्स के लिए सबसे तेज़ हैं।
f0b0s

आपका फ़िल्टर उदाहरण py2k
SilentGhost

2
@ f0b0s-iu9-info: क्या आपने इसे टाइम किया? मेरी मशीन पर (py3k) री फिल्टर के मुकाबले दोगुना तेज है isdigit, जेनरेटर isdigtउनके बीच में आधा है
साइलेंटगॉस्ट

@SilentGhost: धन्यवाद, मैं py2k से IDLE का उपयोग कर रहा था। यह अब तय हो गया है।
जोहो सिल्वा

1
@ चमेली बस rकच्चे तार के लिए उपयोग करें :re.sub(r"\D+", "", "aas30dsa20")
मिच मैकमाबर्स

64
s=''.join(i for i in s if i.isdigit())

एक और जनरेटर संस्करण।


इसे मार दिया .. + 1 और भी बेहतर होता अगर लामड़ा का इस्तेमाल किया जाता
बारात रविकुमार

17

आप फ़िल्टर का उपयोग कर सकते हैं:

filter(lambda x: x.isdigit(), "dasdasd2313dsa")

Python3.0 पर आपको इसे शामिल करना होगा (थोड़े बदसूरत :()

''.join(filter(lambda x: x.isdigit(), "dasdasd2313dsa"))

केवल py2k में, py3k में यह एक जनरेटर लौटाता है
साइलेंटगॉस्ट

यह सुनिश्चित strकरने के listलिए परिवर्तित करें कि यह py2 और py3 दोनों पर काम करता है:''.join(filter(lambda x: x.isdigit(), list("dasdasd2313dsa")))
Luiz C.

13

बायर के जवाब की तर्ज पर:

''.join(i for i in s if i.isdigit())

नहीं, यह ऋणात्मक संख्याओं के लिए काम नहीं करेगा क्योंकि -कोई अंक नहीं है।
ओली

12

आप इसे Regex का उपयोग करके आसानी से कर सकते हैं

>>> import re
>>> re.sub("\D","","£70,000")
70000

अब तक का सबसे आसान तरीका
Iorek

5
यह जोहो सिल्वा के उत्तर से अलग कैसे है, जो 7 साल पहले प्रदान किया गया था?
jww

7
x.translate(None, string.digits)

स्ट्रिंग से सभी अंकों को हटा देगा। अक्षरों को हटाने और अंकों को रखने के लिए, यह करें:

x.translate(None, string.letters)

3
मुझे एक TypeError: अनुवाद मिलता है () दिया गया एक तर्क (2 दिया)। इसकी वर्तमान स्थिति में यह सवाल क्यों उठाया गया, यह काफी निराशाजनक है।
बोबोर्ट

python 2 से 3 में परिवर्तित किया गया अनुवाद। python 3 में इस पद्धति का उपयोग करने वाला सिंटैक्स x.translate (str.maketrans ('', ', string.digits)) और x.translate (str.maketrans (' ',' '' ') है। , string.ascii_letters))। इनमें से न तो स्ट्रिप्स सफेद जगह। मैं वास्तव में अब इस दृष्टिकोण की सिफारिश नहीं करूंगा ...
ज़क्सआर

5

सेशन में टिप्पणियों का उल्लेख है कि वह दशमलव स्थान रखना चाहता है। यह वर्णों को सूचीबद्ध करने के लिए स्पष्ट रूप से सूचीबद्ध करके पुनः.सुब विधि (दूसरे और IMHO सर्वोत्तम उत्तर के अनुसार) के साथ किया जा सकता है

>>> re.sub("[^0123456789\.]","","poo123.4and5fish")
'123.45'

"Poo123.4and.5fish" के बारे में क्या?
जन तोजरना

मेरे कोड में मैं इनपुट स्ट्रिंग में अवधियों की संख्या की जांच करता हूं और यदि एक से अधिक है तो एक त्रुटि उठाएं।
रोजर हीथकोट

4

पायथन 3 के लिए एक तेज़ संस्करण:

# xx3.py
from collections import defaultdict
import string
_NoneType = type(None)

def keeper(keep):
    table = defaultdict(_NoneType)
    table.update({ord(c): c for c in keep})
    return table

digit_keeper = keeper(string.digits)

यहाँ एक प्रदर्शन तुलना बनाम रेगेक्स है:

$ python3.3 -mtimeit -s'import xx3; x="aaa12333bb445bb54b5b52"' 'x.translate(xx3.digit_keeper)'
1000000 loops, best of 3: 1.02 usec per loop
$ python3.3 -mtimeit -s'import re; r = re.compile(r"\D"); x="aaa12333bb445bb54b5b52"' 'r.sub("", x)'
100000 loops, best of 3: 3.43 usec per loop

तो यह मेरे लिए रेगेक्स की तुलना में 3 गुना अधिक तेज है। यह class Delऊपर से भी तेज है , क्योंकि defaultdictइसके सभी लुकअप सी (धीमी) पायथन के बजाय C में हैं। तुलना के लिए यहां मेरे उसी सिस्टम पर वह संस्करण है।

$ python3.3 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)'
100000 loops, best of 3: 13.6 usec per loop

3

एक जनरेटर अभिव्यक्ति का उपयोग करें:

>>> s = "foo200bar"
>>> new_s = "".join(i for i in s if i in "0123456789")

इसके बजाय''.join(n for n in foo if n.isdigit())
shxfee

2

बदसूरत लेकिन काम करता है:

>>> s
'aaa12333bb445bb54b5b52'
>>> a = ''.join(filter(lambda x : x.isdigit(), s))
>>> a
'1233344554552'
>>>

तुम क्यों करते हो list(s)?
साइलेंटगॉस्ट

@SilentGhost यह मेरी गलतफहमी है। इसने धन्यवाद को सही कर लिया :)
गैंट

दरअसल, इस पद्धति के साथ, मुझे नहीं लगता कि आपको "जॉइन" करने की आवश्यकता है। filter(lambda x: x.isdigit(), s)मेरे लिए ठीक काम किया। ... ओह, यह इसलिए है क्योंकि मैं 2.7 पायथन का उपयोग कर रहा हूं।
बॉबॉर्ट

1
$ python -mtimeit -s'import re;  x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'

100000 छोरों, 3 का सबसे अच्छा: 2.48 usec प्रति पाश

$ python -mtimeit -s'import re; x="aaa12333bab445bb54b5b52"' '"".join(re.findall("[a-z]+",x))'

100000 लूप, 3 का सर्वश्रेष्ठ: 2.02 प्रति लूप usec

$ python -mtimeit -s'import re;  x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'

100000 लूप्स, सर्वश्रेष्ठ 3: 2.37 usec प्रति लूप

$ python -mtimeit -s'import re; x="aaa12333bab445bb54b5b52"' '"".join(re.findall("[a-z]+",x))'

100000 लूप्स, सर्वश्रेष्ठ 3: 1.97 usec प्रति लूप

मैंने देखा था कि ज्वाइन उप की तुलना में तेज है।


आप दो तरीकों को दो बार क्यों दोहरा रहे हैं? और क्या आप यह बता सकते हैं कि आपका उत्तर स्वीकृत से अलग कैसे है?
22 जनवरी को 22 जनवरी को जंज तंजर

दोनों एक ही आउटपुट का परिणाम है। लेकिन, मैं सिर्फ यह दिखाना चाहता हूं कि नतीजों में उप विधि तेजी से जुड़ती है।
अनिलरेड्डी

वे नहीं करते हैं, आपका कोड विपरीत करता है। और आपके पास चार माप भी हैं लेकिन केवल दो तरीके हैं।
जन तोजर

1

आप प्रत्येक वर्ण पढ़ सकते हैं। यदि यह अंक है, तो इसे उत्तर में शामिल करें। str.isdigit() विधि एक तरह से करता है, तो एक चरित्र अंकों है पता करने के लिए है।

your_input = '12kjkh2nnk34l34'
your_output = ''.join(c for c in your_input if c.isdigit())
print(your_output) # '1223434'

यह f0b0s द्वारा उत्तर से कैसे भिन्न है? अगर आपको और जानकारी लाने की बजाय आपको उस जवाब को संपादित करना चाहिए
chevybow

0

एक लाइनर नहीं बल्कि बहुत सरल:

buffer = ""
some_str = "aas30dsa20"

for char in some_str:
    if not char.isdigit():
        buffer += char

print( buffer )

0

मैंने इसका इस्तेमाल किया। 'letters'उन सभी पत्रों को शामिल करना चाहिए जिनसे आप छुटकारा पाना चाहते हैं:

Output = Input.translate({ord(i): None for i in 'letters'}))

उदाहरण:

Input = "I would like 20 dollars for that suit" Output = Input.translate({ord(i): None for i in 'abcdefghijklmnopqrstuvwxzy'})) print(Output)

आउटपुट: 20

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.