2014-09-24 33 views
1

在代碼審查的挑戰,我最近有下面的代碼名爲unpythonic:Python的v Unpythonic

def word_count(string): 
wc_dict = {} 
word = "" 
index = 0 
while index < len(string): 

    if string[index].isalnum(): 
     word = word + string[index] 
     index += 1 
    else: 
     if word: 
      if word.lower() in wc_dict: 
       wc_dict[word.lower()] += 1 
      else: 
       wc_dict[word.lower()] = 1 
     word = "" 
     index += 1 

if word: 
    if word.lower() in wc_dict: 
     wc_dict[word.lower()] += 1 
    else: 
     wc_dict[word.lower()] = 1 

return wc_dict  

我還提交不同的代碼,我用Ruby寫了一個挑戰,有這樣的解決方案稱爲「Python化」 。

代碼是什麼意思是Pythonic/Unpythonic?

+0

Unpythonic = Pythetic :-) – paxdiablo 2014-09-24 05:07:34

+0

你可以直接迭代字符串,你知道。這可能是我發現的一件事。 – Makoto 2014-09-24 05:09:21

+1

[谷歌搜索「pythonic」](https://www.google.com/search?q=pythonic)給出了一些非常明確的結果解釋該術語。 – user2357112 2014-09-24 05:13:01

回答

4

我會說「pythonic」意思是「符合python的通常習語,以便編寫易於閱讀的代碼」。你的例子不是pythonic,因爲它可能(可能)更容易寫出來。

例如使用正則表達式+ collections.Counter原來這成爲非常明顯的2 - 內膽:

words = re.findall(r'\w+', string) 
wc_dict = collections.Counter(words) 

如果你只期望能夠在空白分裂,這使得它更容易:時間

wc_dict = collections.Counter(string.split()) 

95%如果你使用字符串中的單個字符,還有更好的方法。

1

我非常同意@ mgilson對上面(un-)Pythonic的定義,但會在這個案例上再擴展一點。

我想說這個代碼可能被描述爲「非pythonic」的原因之一是因爲它似乎是一個相當直接的C代碼翻譯來做同樣的事情。我還看到許多Python代碼似乎基於熟悉Java或C#以及它們各自的數據結構,標準庫和風格約定。

除了dict之外,OP的代碼似乎沒有使用任何Python的高級數據結構或迭代功能。

即使在使用dict時,它也是一種不太流利的方式。此代碼:

if word.lower() in wc_dict: 
    wc_dict[word.lower()] += 1 
else: 
    wc_dict[word.lower()] = 1 

...可以用更簡潔的版本替換平凡(這也可以縮短到一個班輪與defaultdict):

wc_dict.setdefault(word.lower(), 0) 
wc_dict[word.lower()] += 1 

無意爲順便提一下,批評OP是一位深思熟慮的程序員:這是一個看似合理和正確的算法來解決這個問題。它只是沒有利用有經驗的用戶熟悉的許多Python功能。

+0

不用擔心批評;我仍然是一個新手,只是意識到解決問題通常有比1(或2,3)更多的方法。 – 2014-09-24 17:53:41

+0

是的,我想強調的是,從我所能看到的情況來看,這僅僅是缺乏熟悉感,而不是缺乏清晰的思維。 [The Python of Zen](http://legacy.python.org/dev/peps/pep-0020/)說:「應該有一個 - 最好只有一個 - 明顯的方式來做到這一點。「這引發了很多關於複雜問題的爭論和判斷,但我發現的一個好處是,大多數有經驗的Python程序員傾向於考慮這個問題並抵制以模糊或難以理解的方式解決問題。 – 2014-09-24 18:11:37