انقسام من قبل الفاصلة والمساحة البيضاء في بيثون
-
28-09-2019 - |
سؤال
لدي بعض رمز بيثون الذي ينقسم على الفاصلة ، ولكن لا يجرد المسافة البيضاء:
>>> string = "blah, lots , of , spaces, here "
>>> mylist = string.split(',')
>>> print mylist
['blah', ' lots ', ' of ', ' spaces', ' here ']
أفضل أن ينتهي بإزالة المسافة البيضاء مثل هذا:
['blah', 'lots', 'of', 'spaces', 'here']
أدرك أنه يمكنني الحصول على حلقة من خلال القائمة وقطعة () كل عنصر ، لكن بما أن هذا بيثون ، أعتقد أن هناك طريقة أسرع وأسهل وأكثر أناقة للقيام بذلك.
المحلول
استخدم فهم القائمة - أبسط ، وسهلة القراءة مثل أ for
عقدة.
my_string = "blah, lots , of , spaces, here "
result = [x.strip() for x in my_string.split(',')]
# result is ["blah", "lots", "of", "spaces", "here"]
نرى: مستندات بيثون على فهم القائمة
شرح جيد 2 الثاني لفهم القائمة.
نصائح أخرى
تقسيم باستخدام تعبير منتظم. لاحظ أنني جعلت القضية أكثر عمومية مع المساحات الرائدة. فهم القائمة هو إزالة السلاسل الفارغة في الأمام والخلف.
>>> import re
>>> string = " blah, lots , of , spaces, here "
>>> pattern = re.compile("^\s+|\s*,\s*|\s+$")
>>> print([x for x in pattern.split(string) if x])
['blah', 'lots', 'of', 'spaces', 'here']
هذا يعمل حتى لو ^\s+
لا يتطابق:
>>> string = "foo, bar "
>>> print([x for x in pattern.split(string) if x])
['foo', 'bar']
>>>
إليك لماذا تحتاج إلى ^ S+:
>>> pattern = re.compile("\s*,\s*|\s+$")
>>> print([x for x in pattern.split(string) if x])
[' blah', 'lots', 'of', 'spaces', 'here']
رؤية المساحات الرائدة في بلاه؟
التوضيح: أعلاه يستخدم مترجم Python 3 ، ولكن النتائج هي نفسها في Python 2.
جئت لأضيف:
map(str.strip, string.split(','))
ولكن رأى أنه قد ذكره بالفعل من قبل جيسون أورندرف في تعليق.
قراءة تعليق Glenn Maynard في نفس الإجابة التي تشير إلى القائمة على شمولية على الخريطة ، بدأت أتساءل عن السبب. لقد افترضت أنه يعني لأسباب الأداء ، ولكن بالطبع ربما كان يعني لأسباب أسلوبية ، أو أي شيء آخر (جلين؟).
لذلك تم الكشف عن اختبار سريع (ربما معيبة؟) على الصندوق الذي يطبق الأساليب الثلاثة في حلقة:
[word.strip() for word in string.split(',')]
$ time ./list_comprehension.py
real 0m22.876s
map(lambda s: s.strip(), string.split(','))
$ time ./map_with_lambda.py
real 0m25.736s
map(str.strip, string.split(','))
$ time ./map_with_str.strip.py
real 0m19.428s
صناعة map(str.strip, string.split(','))
الفائز ، على الرغم من أنه يبدو أنهم جميعًا في نفس الملعب.
من المؤكد أنه على الرغم من أنه لا ينبغي بالضرورة استبعاد الخريطة (مع أو بدون Lambda) لأسباب الأداء ، وبالنسبة لي يكون ذلك واضحًا على الأقل مثل فهم القائمة.
يحرر:
Python 2.6.5 على Ubuntu 10.04
فقط قم بإزالة المساحة البيضاء من السلسلة قبل تقسيمها.
mylist = my_string.replace(' ','').split(',')
أعلم أن هذا قد تم الرد عليه بالفعل ، ولكن إذا انتهت من القيام بذلك كثيرًا ، فقد تكون التعبيرات العادية طريقة أفضل للذهاب:
>>> import re
>>> re.sub(r'\s', '', string).split(',')
['blah', 'lots', 'of', 'spaces', 'here']
ال \s
يطابق أي حرف من المسافة البيضاء ، ونستبدلها بسلسلة فارغة ''
. يمكنك العثور على مزيد من المعلومات هنا: http://docs.python.org/library/re.html#re.sub
s = 'bla, buu, jii'
sp = []
sp = s.split(',')
for st in sp:
print st
import re
result=[x for x in re.split(',| ',your_string) if x!='']
هذا يفي بالغرض بالنسبة لي.
re
(كما في التعبيرات العادية) يسمح بالقسمة على أحرف متعددة في وقت واحد:
$ string = "blah, lots , of , spaces, here "
$ re.split(', ',string)
['blah', 'lots ', ' of ', ' spaces', 'here ']
هذا لا يعمل بشكل جيد لسلسلة مثالك ، ولكنه يعمل بشكل جيد للحصول على قائمة مفصول بين الفواصل. لسلسلة المثال الخاصة بك ، يمكنك الجمع بين قوة إعادة التقسيم أنماط regex للحصول على تأثير "انقسام على هذا أو هذا".
$ re.split('[, ]',string)
['blah',
'',
'lots',
'',
'',
'',
'',
'of',
'',
'',
'',
'spaces',
'',
'here',
'']
لسوء الحظ ، هذا قبيح ، لكن أ filter
سيفعل الحيلة:
$ filter(None, re.split('[, ]',string))
['blah', 'lots', 'of', 'spaces', 'here']
هاهو!
map(lambda s: s.strip(), mylist)
سيكون أفضل قليلاً من الحلقات الصريحة. أو لكل شيء في وقت واحد: map(lambda s:s.strip(), string.split(','))
import re
mylist = [x for x in re.compile('\s*[,|\s+]\s*').split(string)
ببساطة ، فاصلة أو مساحات بيضاء واحدة على الأقل مع/بدون مساحات بيضاء تسبق/التالية.
أرجوك حاول!
map(lambda s: s.strip(), mylist)
سيكون أفضل قليلاً من الحلقات الصريحة.
أو لكل شيء في وقت واحد:
map(lambda s:s.strip(), string.split(','))
هذا في الأساس كل ما تحتاجه.