if / other trong một danh sách hiểu


Câu trả lời:


1460

Bạn hoàn toàn có thể làm điều đó. Đó chỉ là một vấn đề đặt hàng:

[unicode(x.strip()) if x is not None else '' for x in row]

Nói chung,

[f(x) if condition else g(x) for x in sequence]

Và, chỉ để hiểu danh sách với các ifđiều kiện,

[f(x) for x in sequence if condition]

Lưu ý rằng điều này thực sự sử dụng một cấu trúc ngôn ngữ khác, một biểu thức có điều kiện , bản thân nó không phải là một phần của cú pháp hiểu , trong khi phần ifsau for…inlà một phần của việc hiểu danh sách và được sử dụng để lọc các phần tử từ nguồn lặp.


Biểu thức điều kiện có thể được sử dụng trong tất cả các loại tình huống mà bạn muốn chọn giữa hai giá trị biểu thức dựa trên một số điều kiện. Điều này không giống như toán tử ternary ?:tồn tại trong các ngôn ngữ khác . Ví dụ:

value = 123
print(value, 'is', 'even' if value % 2 == 0 else 'odd')

141
Lưu ý rằng if / other ở đây bây giờ là cú pháp "toán tử ternary" và không liệt kê cú pháp hiểu.
Adam Vandenberg

8
Đó là lý do tại sao tôi thích đặt toán tử ternary trong ngoặc, nó làm cho rõ ràng hơn rằng đó chỉ là một biểu thức bình thường, không phải là một sự hiểu biết.
Jochen Ritzel

17
Vì vậy, mẹo là "Trong danh sách nén tôi viết nếu trước đó thì tôi cũng phải thêm phần khác". bởi vì nếu l = [ 2, 3, 4, 5]sau đó [x if x % 2 == 0 for x in l]tôi cho tôi lỗi trong khi [x if x % 2 == 0 else 200 for x in l]làm việc. Có tôi biết để lọc nó tôi nên viết [ x for x in l if x % 2 == 0]. Xin lỗi vì đã làm phiền. Cảm ơn câu trả lời của bạn.
Grijesh Chauhan

5
Các tài liệu python đề cập đến toán tử ternary . Lưu ý rằng nó yêu cầu khác, hoặc nó không hoạt động.
ness101

4
@Drewdin Danh sách hiểu không hỗ trợ phá vỡ trong quá trình lặp lại của nó. Bạn sẽ phải sử dụng một vòng lặp bình thường sau đó.
chọc

44

Một chiều:

def change(f):
    if f is None:
        return unicode(f.strip())
    else:
        return ''

row = [change(x) for x in row]

Mặc dù sau đó bạn có:

row = map(change, row)

Hoặc bạn có thể sử dụng một lambda nội tuyến.


13
Đây cũng là một kỹ thuật tốt (có thể chỉ) để sử dụng khi bạn phải xử lý các trường hợp ngoại lệ có thể xảy ra từ ifbiểu thức hoặc mã trong elsekhối câu lệnh của nó hoặc s. Câu trả lời được chấp nhận là tốt hơn cho các trường hợp đơn giản.
martineau

37

Đây là một ví dụ minh họa khác:

>>> print(", ".join(["ha" if i else "Ha" for i in range(3)]) + "!")
Ha, ha, ha!

Nó khai thác thực tế if iđánh giá Falsecho 0Truecho tất cả các giá trị khác được tạo bởi hàm range(). Do đó, việc hiểu danh sách đánh giá như sau:

>>> ["ha" if i else "Ha" for i in range(3)]
['Ha', 'ha', 'ha']

37

Vấn đề cụ thể đã được giải quyết trong các câu trả lời trước, vì vậy tôi sẽ giải quyết ý tưởng chung về việc sử dụng các điều kiện bên trong danh sách hiểu.

Dưới đây là một ví dụ cho thấy cách các điều kiện có thể được viết trong phần hiểu danh sách:

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

Lưu ý rằng trong phần hiểu danh sách đầu tiên X_non_str, thứ tự là:

biểu thức cho mục trong iterable nếu điều kiện

và trong phần hiểu danh sách cuối cùng cho X_str_changed, thứ tự là:

biểu thức1 nếu điều kiện khác biểu thức2 cho mục trong iterable

Tôi luôn thấy khó để nhớ rằng expresseion1 có được trước nếuexpression2 có được sau khi khác . Đầu tôi muốn cả hai trước hoặc sau.

Tôi đoán nó được thiết kế như vậy bởi vì nó giống với ngôn ngữ bình thường, ví dụ: "Tôi muốn ở bên trong nếu trời mưa, nếu không tôi muốn ra ngoài"

Trong tiếng Anh đơn giản , hai loại hiểu danh sách được đề cập ở trên có thể được nêu là:

Chỉ với if:

extract_apple cho apple trong box_of_apples nếu apple_is_ripe

và với if/else

mark_apple nếu apple_is_ripe khác left_it_unmarked cho apple trong box_of_apples


7

Các giải pháp khác là tuyệt vời cho một if/ elsexây dựng. Tuy nhiên, các báo cáo ternary trong phạm vi hiểu danh sách được cho là khó đọc.

Sử dụng một chức năng hỗ trợ khả năng đọc, nhưng một giải pháp như vậy rất khó để mở rộng hoặc điều chỉnh trong quy trình làm việc trong đó ánh xạ là một đầu vào. Một từ điển có thể làm giảm bớt những mối quan tâm này:

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', '']

1

Nó có liên quan đến cách thực hiện việc hiểu danh sách.

Hãy ghi nhớ những điều sau:

[ expression for item in list if conditional ]

Tương đương với:

for item in list:
    if conditional:
        expression

Trường hợp expressiontrong một định dạng hơi khác nhau (nghĩ rằng chuyển đổi chủ ngữ và trật tự động từ trong một câu).

Do đó, mã của bạn [x+1 for x in l if x >= 45]thực hiện điều này:

for x in l:
    if x >= 45:
        x+1

Tuy nhiên, mã [x+1 if x >= 45 else x+5 for x in l]này thực hiện điều này (sau khi sắp xếp lại expression):

for x in l:
    if x>=45: x+1
    else: x+5

0

Không có nhu cầu về ternary nếu / thì / khác. Theo tôi câu hỏi của bạn gọi cho câu trả lời này:

row = [unicode((x or '').strip()) for x in row]

0

Tạo một danh sách từ các mục trong một lần lặp

Có vẻ tốt nhất trước tiên là khái quát tất cả các hình thức có thể hơn là đưa ra câu trả lời cụ thể cho các câu hỏi. Mặt khác, người đọc sẽ không biết câu trả lời đã được xác định như thế nào. Dưới đây là một vài hình thức tổng quát mà tôi đã nghĩ ra trước khi tôi đau đầu cố gắng quyết định xem một điều khoản khác có thể được sử dụng ở dạng cuối cùng hay không.

[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]

Giá trị của itemkhông cần phải được sử dụng trong bất kỳ mệnh đề điều kiện nào. A conditional3có thể được sử dụng như một công tắc để thêm hoặc không thêm giá trị vào danh sách đầu ra.

Ví dụ: để tạo một danh sách mới giúp loại bỏ các chuỗi trống hoặc chuỗi khoảng trắng khỏi danh sách chuỗi gốc:

newlist = [s for s in firstlist if s.strip()]

1
Cái thứ hai đưa ra một lỗi khi Tim trả lời trong bình luận của anh ấy, xem thêm các câu điều kiện trong tài liệu python. Điều này khá khó đọc với tôi. Tóm tắt: chỉ this if condition else thathoặc một biểu thức bình thường được cho phép. Không value = this if condition(có thể đạt được với value = this if condition else None)
Anderium

0

Bạn có thể kết hợp logic có điều kiện theo cách hiểu:

 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])

-2
# 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]

Vì vậy, cho bạn: row = [('', unicode(x.strip()))[x is not None] for x in row]


Không gì "Affichage de ..." nghĩa là gì? Có phải là tiếng Pháp không?
Peter Mortensen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.