ฉันจะทำสิ่งต่อไปนี้ใน Python ได้อย่างไร
row = [unicode(x.strip()) for x in row if x is not None else '']
เป็นหลัก:
- แทนที่ Nones ทั้งหมดด้วยสตริงว่างแล้ว
- ดำเนินฟังก์ชั่น
ฉันจะทำสิ่งต่อไปนี้ใน Python ได้อย่างไร
row = [unicode(x.strip()) for x in row if x is not None else '']
เป็นหลัก:
คำตอบ:
คุณสามารถทำเช่นนั้นได้ทั้งหมด มันเป็นเพียงปัญหาการสั่งซื้อ:
[unicode(x.strip()) if x is not None else '' for x in row]
โดยทั่วไปแล้ว
[f(x) if condition else g(x) for x in sequence]
และสำหรับรายการความเข้าใจที่มีif
เงื่อนไขเท่านั้น
[f(x) for x in sequence if condition]
โปรดทราบว่าสิ่งนี้ใช้โครงสร้างภาษาที่แตกต่างกันซึ่งเป็นการแสดงออกแบบมีเงื่อนไขซึ่งตัวมันเองไม่ได้เป็นส่วนหนึ่งของไวยากรณ์ความเข้าใจในขณะที่ส่วนif
หลังfor…in
ของรายการนั้นเป็นส่วนหนึ่งของความเข้าใจในรายการและใช้ในการกรององค์ประกอบจากแหล่งที่มา
การแสดงออกแบบมีเงื่อนไขสามารถใช้ในสถานการณ์ทุกประเภทที่คุณต้องการเลือกระหว่างสองค่านิพจน์ตามเงื่อนไขบางอย่าง นี้จะเป็นเช่นเดียวกับผู้ประกอบการ ternary?:
ที่มีอยู่ในภาษาอื่น ๆ ตัวอย่างเช่น:
value = 123
print(value, 'is', 'even' if value % 2 == 0 else 'odd')
l = [ 2, 3, 4, 5]
แล้วก็[x if x % 2 == 0 for x in l]
ให้ฉันข้อผิดพลาดในขณะที่[x if x % 2 == 0 else 200 for x in l]
ทำงาน [ x for x in l if x % 2 == 0]
ใช่ฉันรู้ว่าการกรองฉันควรจะเขียน ขออภัยที่อนิจจา ขอบคุณสำหรับคำตอบ.
ทางเดียว:
def change(f):
if f is None:
return unicode(f.strip())
else:
return ''
row = [change(x) for x in row]
แม้ว่าคุณจะมี:
row = map(change, row)
หรือคุณสามารถใช้แลมบ์ดาอินไลน์
if
นิพจน์หรือรหัสในelse
บล็อกคำสั่งหรือ คำตอบที่ยอมรับได้ดีกว่าสำหรับกรณีง่าย ๆ
นี่เป็นอีกตัวอย่างที่เป็นตัวอย่าง:
>>> print(", ".join(["ha" if i else "Ha" for i in range(3)]) + "!")
Ha, ha, ha!
มันใช้ประโยชน์จากความจริงที่ว่าif i
ประเมินFalse
สำหรับ0
และTrue
สำหรับค่าอื่น ๆ range()
ทั้งหมดที่สร้างโดยฟังก์ชั่น ดังนั้นรายการความเข้าใจจะประเมินดังนี้:
>>> ["ha" if i else "Ha" for i in range(3)]
['Ha', 'ha', 'ha']
ปัญหาที่เฉพาะเจาะจงได้รับการแก้ไขแล้วในคำตอบก่อนหน้าดังนั้นฉันจะพูดถึงความคิดทั่วไปของการใช้เงื่อนไขภายในรายการความเข้าใจ
นี่คือตัวอย่างที่แสดงให้เห็นว่าสามารถเขียนเงื่อนไขในความเข้าใจของรายการได้อย่างไร:
X = [1.5, 2.3, 4.4, 5.4, 'n', 1.5, 5.1, 'a'] # Original list
# Extract non-strings from X to new list
X_non_str = [el for el in X if not isinstance(el, str)] # When using only 'if', put 'for' in the beginning
# Change all strings in X to 'b', preserve everything else as is
X_str_changed = ['b' if isinstance(el, str) else el for el in X] # When using 'if' and 'else', put 'for' in the end
โปรดทราบว่าในรายการแรกที่เข้าใจสำหรับX_non_str
การสั่งซื้อคือ:
การแสดงออก สำหรับ รายการ ใน iterable ถ้า เงื่อนไข
และในรายการสุดท้ายที่เข้าใจX_str_changed
คือลำดับคือ:
expression1 ถ้า condition else expression2 สำหรับ item ใน iterable
ฉันมักจะพบว่ามันยากที่จะจำไว้ว่าexpresseion1จะต้องมีก่อนถ้าและExpression2จะเป็นหลังจากที่มีคนอื่น หัวของฉันต้องการให้ทั้งก่อนและหลัง
ฉันเดาว่ามันถูกออกแบบมาเช่นนั้นเพราะคล้ายกับภาษาปกติเช่น "ฉันต้องการอยู่ข้างในถ้าฝนตกมิฉะนั้นฉันก็อยากออกไปข้างนอก"
ในภาษาอังกฤษธรรมดาความเข้าใจในรายการทั้งสองประเภทที่กล่าวถึงข้างต้นอาจกล่าวได้ว่า:
มีเพียงif
:
extract_apple สำหรับ apple ใน box_of_apples ถ้า apple_is_ripe
และด้วย if/else
mark_apple หาก apple_is_ripe ปล่อยให้แอปเปิ้ล_it_unmark อื่น ๆ อยู่ในbox_of_apples
โซลูชันอื่น ๆ นั้นยอดเยี่ยมสำหรับงานเดี่ยวif
/ else
งานสร้าง อย่างไรก็ตามข้อความไตรภาคภายในรายการความเข้าใจนั้นยากที่จะอ่าน
การใช้ฟังก์ชั่นช่วยในการอ่าน แต่การแก้ปัญหาดังกล่าวเป็นการยากที่จะขยายหรือปรับในเวิร์กโฟลว์ที่การทำแผนที่เป็นอินพุต พจนานุกรมสามารถบรรเทาข้อกังวลเหล่านี้:
row = [None, 'This', 'is', 'a', 'filler', 'test', 'string', None]
d = {None: '', 'filler': 'manipulated'}
res = [d.get(x, x) for x in row]
print(res)
['', 'This', 'is', 'a', 'manipulated', 'test', 'string', '']
มันเกี่ยวกับวิธีการทำ list comprehension
โปรดจำไว้ว่า:
[ expression for item in list if conditional ]
เทียบเท่ากับ:
for item in list:
if conditional:
expression
ในกรณีที่expression
อยู่ในรูปแบบที่แตกต่างกันเล็กน้อย (คิดว่าการเปลี่ยนเรื่องและคำกริยาในประโยค)
ดังนั้นรหัสของคุณ[x+1 for x in l if x >= 45]
ทำสิ่งนี้:
for x in l:
if x >= 45:
x+1
อย่างไรก็ตามรหัสนี้[x+1 if x >= 45 else x+5 for x in l]
ทำสิ่งนี้ (หลังจากจัดเรียงใหม่expression
):
for x in l:
if x>=45: x+1
else: x+5
ไม่จำเป็นต้องมี ternary หาก / / / อื่น ๆ ในความคิดของฉันคำถามของคุณเรียกหาคำตอบนี้:
row = [unicode((x or '').strip()) for x in row]
ทำรายการจากรายการใน iterable
ดูเหมือนจะเป็นการดีที่สุดที่จะสรุปแบบฟอร์มทั้งหมดที่เป็นไปได้ก่อนแทนที่จะให้คำตอบเฉพาะกับคำถาม มิฉะนั้นผู้อ่านจะไม่ทราบว่าคำตอบถูกกำหนดแล้ว นี่คือรูปแบบทั่วไปบางอย่างที่ฉันคิดขึ้นก่อนที่ฉันจะปวดหัวพยายามที่จะตัดสินใจว่าประโยคสุดท้ายสามารถใช้ในรูปแบบสุดท้ายได้หรือไม่
[expression1(item) for item in iterable]
[expression1(item) if conditional1 for item in iterable]
[expression1(item) if conditional1 else expression2(item) for item in iterable]
[expression1(item) if conditional1 else expression2(item) for item in iterable if conditional2]
ค่าของitem
ไม่จำเป็นต้องนำมาใช้ในใด ๆ ของคำสั่งเงื่อนไข conditional3
สามารถใช้เป็นสวิทช์ที่จะเพิ่มหรือไม่เพิ่มมูลค่าให้กับรายการที่ส่งออก
ตัวอย่างเช่นในการสร้างรายการใหม่ที่กำจัดสตริงว่างหรือสตริงช่องว่างจากรายการสตริงดั้งเดิม:
newlist = [s for s in firstlist if s.strip()]
this if condition else that
อนุญาตให้ใช้ได้เฉพาะนิพจน์ปกติเท่านั้น ไม่ใช่value = this if condition
(ซึ่งสามารถทำได้ด้วยvalue = this if condition else None
)
คุณสามารถรวมตรรกะตามเงื่อนไขในความเข้าใจ:
ps = PorterStemmer()
stop_words_english = stopwords.words('english')
best = sorted(word_scores.items(), key=lambda x: x[1], reverse=True)[:10000]
bestwords = set([w for w, s in best])
def best_word_feats(words):
return dict([(word, True) for word in words if word in bestwords])
# with stemmer
def best_word_feats_stem(words):
return dict([(ps.stem(word), True) for word in words if word in bestwords])
# with stemmer and not stopwords
def best_word_feats_stem_stop(words):
return dict([(ps.stem(word), True) for word in words if word in bestwords and word not in stop_words_english])
# coding=utf-8
def my_function_get_list():
my_list = [0, 1, 2, 3, 4, 5]
# You may use map() to convert each item in the list to a string,
# and then join them to print my_list
print("Affichage de my_list [{0}]".format(', '.join(map(str, my_list))))
return my_list
my_result_list = [
(
number_in_my_list + 4, # Condition is False : append number_in_my_list + 4 in my_result_list
number_in_my_list * 2 # Condition is True : append number_in_my_list * 2 in my_result_list
)
[number_in_my_list % 2 == 0] # [Condition] If the number in my list is even
for number_in_my_list in my_function_get_list() # For each number in my list
]
print("Affichage de my_result_list [{0}]".format(', '.join(map(str, my_result_list))))
(venv) $ python list_comp.py
Affichage de my_list [0, 1, 2, 3, 4, 5]
Affichage de my_result_list [0, 5, 4, 7, 8, 9]
ดังนั้นสำหรับคุณ:
row = [('', unicode(x.strip()))[x is not None] for x in row]