Python成語返回第一項或None


Answers

最好的方法是:

a = get_list()
return a[0] if a else None

你也可以在一行中完成,但程序員讀起來要困難得多:

return (get_list()[:1] or [None])[0]
Question

我確信有一個更簡單的方法可以做到這一點,這對我來說不會發生。

我打電話給一堆返回列表的方法。 該列表可能為空。 如果列表非空,我想返回第一個項目; 否則,我想返回None。 此代碼有效:

my_list = get_list()
if len(my_list) > 0: return my_list[0]
return None

在我看來,做這件事應該有一個簡單的一行成語,但對於我來說,我想不起來。 在那兒?

編輯:

我在這裡尋找單行表達的原因並不是我喜歡難以置信的簡潔代碼,而是因為我不得不編寫如下這樣的代碼:

x = get_first_list()
if x:
    # do something with x[0]
    # inevitably forget the [0] part, and have a bug to fix
y = get_second_list()
if y:
    # do something with y[0]
    # inevitably forget the [0] part AGAIN, and have another bug to fix

我想要做的事情當然可以用一個函數來完成(可能會):

def first_item(list_or_none):
    if list_or_none: return list_or_none[0]

x = first_item(get_first_list())
if x:
    # do something with x
y = first_item(get_second_list())
if y:
    # do something with y

我發布了這個問題,因為我經常被Python中簡單的表達式所能做到的事情感到驚訝,我認為編寫一個函數是一件很愚蠢的事情,如果有一個簡單的表達式可以做到這一點。 但看到這些答案,這似乎是一個簡單的解決方案。




如果你發現自己試圖從列表理解中抽取第一件事物(或無),你可以切換到一個生成器來執行它,如:

next((x for x in blah if cond), None)

Pro:如果blah不是可編譯的,則可以工作。Con:這是不熟悉的語法。 雖然在ipython中進行黑客入侵和過濾,但這很有用。




我的用例只是設置局部變量的值。

我個人發現嘗試和除了風格清潔劑閱讀

items = [10, 20]
try: first_item = items[0]
except IndexError: first_item = None
print first_item

比切分列表。

items = [10, 20]
first_item = (items[:1] or [None, ])[0]
print first_item



try:
    return a[0]
except IndexError:
    return None



對於它而言,這是另一種可能性。

return None if not get_list() else get_list()[0]

好處:此方法處理get_list為None的情況,不使用try / except或assignment。 據我所知,上述的實現都不能處理這種可能性

垮台:get_list()被調用兩次,這是非常不必要的,特別是當列表很長時和/或在函數被調用時創建。

事實是,在我看來,更多的是“Pythonic”,它提供的代碼是可讀的,而不僅僅是因為你可以製作一行代碼:)我不得不承認,我多次因為不必要地壓縮Python代碼而感到內疚,我很感動,我可以做一個複雜的功能看起來很小:)

編輯:正如用戶“hasen j”在下面評論的那樣,上面的條件表達式在Python 2.5中是新的,如下所述: https://docs.python.org/whatsnew/2.5.html#pep-308 : https://docs.python.org/whatsnew/2.5.html#pep-308 。 謝謝,哈森!




那麼怎麼樣: next(iter(get_list()), None) ? 可能不是這裡最快的,但是標準(從Python 2.6開始)和簡潔。




這個怎麼樣:

(my_list and my_list[0]) or None

注意:對於對象列表,這應該可以正常工作,但是如果按照下面的註釋編號或字符串列表,它可能會返回錯誤的答案。




def head(iterable):
    try:
        return iter(iterable).next()
    except StopIteration:
        return None

print head(xrange(42, 1000)  # 42
print head([])               # None

順便說一句:我會重新將您的一般程序流程改為如下所示:

lists = [
    ["first", "list"],
    ["second", "list"],
    ["third", "list"]
]

def do_something(element):
    if not element:
        return
    else:
        # do something
        pass

for li in lists:
    do_something(head(li))

(盡可能避免重複)




最常用的python慣用方法是在迭代器上使用next(),因為列表是可迭代的 。 就像@JFSebastian在2011年12月13日的評論中所說的那樣。

next(iter(the_list), None)如果the_list為空,則返回None。 請參閱下一個()Python 2.6+

或者如果你確定the_list不是空的:

iter(the_list).next()請參閱iterator.next()Python 2.2+




坦率地說,我認為沒有更好的成語:你的語言清晰簡潔 - 不需要任何“更好”的東西。 也許吧,但是這真的是一個有趣的問題,你可以改變, if len(list) > 0: with if list: - 一個空列表將總是評估為False。

在相關說明中,Python 不是 Perl(不是雙關語!),您不必獲得最酷的代碼。
實際上,我在Python中看到的最糟糕的代碼也非常酷:-)並且完全無法維護。

順便說一下,我在這裡看到的大多數解決方案在列表[0]評估為False時(例如空字符串或零)沒有考慮到 - 在這種情況下,它們都返回None而不是正確的元素。




有幾個人建議做這樣的事情:

list = get_list()
return list and list[0] or None

這在很多情況下都有效,但只有在list [0]不等於0,False或空字符串的情況下它才會起作用。 如果list [0]為0,False或空字符串,則該方法將錯誤地返回None。

我在自己的代碼中創建了這個bug太多次了!