[英]Automate the boring stuff with Python: Comma Code
目前正在閱讀這本初學者書籍,並完成了一個練習項目“逗號代碼”,該項目要求用戶構建一個程序,該程序:
將列表值作為參數並返回一個字符串,其中所有項目由逗號和空格分隔,並在最后一項之前插入並插入。 例如,將以下垃圾郵件列表傳遞給 function 將返回“蘋果、香蕉、豆腐和貓”。 但是您的 function 應該能夠使用傳遞給它的任何列表值。
spam = ['apples', 'bananas', 'tofu', 'cats']
我對問題的解決方案(效果很好):
spam= ['apples', 'bananas', 'tofu', 'cats']
def list_thing(list):
new_string = ''
for i in list:
new_string = new_string + str(i)
if list.index(i) == (len(list)-2):
new_string = new_string + ', and '
elif list.index(i) == (len(list)-1):
new_string = new_string
else:
new_string = new_string + ', '
return new_string
print (list_thing(spam))
我唯一的問題,有什么辦法可以縮短我的代碼? 或者讓它更“pythonic”?
這是我的代碼。
def listTostring(someList):
a = ''
for i in range(len(someList)-1):
a += str(someList[i])
a += str('and ' + someList[len(someList)-1])
print (a)
spam = ['apples', 'bananas', 'tofu', 'cats']
listTostring(spam)
output:蘋果、香蕉、豆腐和貓
使用str.join()
連接帶有分隔符的字符串序列。 如果對除最后一個以外的所有單詞都這樣做,則可以在此處插入' and '
:
def list_thing(words):
if len(words) == 1:
return words[0]
return '{}, and {}'.format(', '.join(words[:-1]), words[-1])
打破這個:
words[-1]
取列表的最后一個元素。 words[:-1]
對列表進行切片以生成一個新列表,其中包含除最后一個單詞之外的所有單詞。
', '.join()
生成一個新字符串,其中str.join()
參數的所有字符串都以', '
連接。 如果輸入列表中只有一個元素,則返回未加入的那個元素。
'{}, and {}'.format()
將逗號連接的單詞和最后一個單詞插入到模板中(使用 Oxford 逗號完成)。
如果傳入一個空列表,上述函數將引發IndexError
異常; 如果您認為空列表是該函數的有效用例,則可以在該函數中專門測試該案例。
所以上面用', '
連接除了最后一個單詞之外的所有單詞,然后用' and '
將最后一個單詞添加到結果中。
請注意,如果只有一個詞,你會得到那個詞; 在這種情況下沒有什么可加入的。 如果有兩個,你會得到'word1 and word 2'
。 更多單詞會產生'word1, word2, ... and lastword'
。
演示:
>>> def list_thing(words):
... if len(words) == 1:
... return words[0]
... return '{}, and {}'.format(', '.join(words[:-1]), words[-1])
...
>>> spam = ['apples', 'bananas', 'tofu', 'cats']
>>> list_thing(spam[:1])
'apples'
>>> list_thing(spam[:2])
'apples, and bananas'
>>> list_thing(spam[:3])
'apples, bananas, and tofu'
>>> list_thing(spam)
'apples, bananas, tofu, and cats'
我使用了不同的方法。 我是初學者,所以我不知道這是否是最干凈的方法。 對我來說,這似乎是最簡單的方法:
spam = ['apples', 'pizza', 'dogs', 'cats']
def comma(items):
for i in range(len(items) -2):
print(items[i], end=", ")# minor adjustment from one beginner to another: to make it cleaner, simply move the ', ' to equal 'end'. the print statement should finish like this --> end=', '
print(items[-2] + 'and ' + items[-1])
comma(spam)
這將給出輸出:
apples, pizza, dogs and cats
這是一個正確處理牛津逗號的解決方案。 它還處理一個空列表,在這種情況下它返回一個空字符串。
def list_thing(seq):
return (' and '.join(seq) if len(seq) <= 2
else '{}, and {}'.format(', '.join(seq[:-1]), seq[-1]))
spam = ['apples', 'bananas', 'tofu', 'cats']
for i in range(1 + len(spam)):
seq = spam[:i]
s = list_thing(seq)
print(i, seq, repr(s))
輸出
0 [] ''
1 ['apples'] 'apples'
2 ['apples', 'bananas'] 'apples and bananas'
3 ['apples', 'bananas', 'tofu'] 'apples, bananas, and tofu'
4 ['apples', 'bananas', 'tofu', 'cats'] 'apples, bananas, tofu, and cats'
FWIW,這是一個使用 if-else 語句而不是條件表達式的稍微易讀的版本:
def list_thing(seq):
if len(seq) <= 2:
return ' and '.join(seq)
else:
return '{}, and {}'.format(', '.join(seq[:-1]), seq[-1])
這是一個可讀性稍差的版本,使用 f 字符串:
def list_thing(seq):
if len(seq) <= 2:
return ' and '.join(seq)
else:
return f"{', '.join(seq[:-1])}, and {seq[-1]}"
請注意,Martijn 的代碼從 2 項列表中生成'apples, and bananas'
。 我的答案在語法上更正確(用英語),但是 Martijn 的答案在技術上更正確,因為它完全按照 OP 的引用中指定的內容(盡管我不同意他對空列表的處理)。
我試過這個,希望這就是你要找的:-
spam= ['apples', 'bananas', 'tofu', 'cats']
def list_thing(list):
#creating a string then splitting it as list with two items, second being last word
new_string=', '.join(list).rsplit(',', 1)
#Using the same method used above to recreate string by replacing the separator.
new_string=' and'.join(new_string)
return new_string
print(list_thing(spam))
我對這個問題的解釋是,單個列表項也將是最后一個列表項,因此需要在它之前插入“和”,以及返回兩個項目列表,它們之間都帶有 ' , and
' 。 因此無需單獨處理單個或兩個項目列表,只需前 n 個項目和最后一個項目。 我還注意到,雖然很好,但當學生遇到這個問題時,許多其他項目使用 Automate the Boring Stuff 文本中沒有教授的模塊和功能(像我這樣的學生在其他地方看到過join
和.format
,但是試圖只使用課文中所教的內容)。
def commacode(passedlist):
stringy = ''
for i in range(len(passedlist)-1):
stringy += str(passedlist[i]) + ', '
# adds all except last item to str
stringy += 'and ' + str(passedlist[len(passedlist)-1])
# adds last item to string, after 'and'
return stringy
您可以通過以下方式處理空列表案例:
def commacode(passedlist):
stringy = ''
try:
for i in range(len(passedlist)-1):
stringy += str(passedlist[i]) + ', '
# adds all except last item to str
stringy += 'and ' + str(passedlist[len(passedlist)-1])
# adds last item to string, after 'and'
return stringy
except IndexError:
return ''
#handles the list out of range error for an empty list by returning ''
其他人已經給出了很好的單行解決方案,但是改進您的實際實現的一個好方法 - 並解決它在元素重復時不起作用的事實 - 是在 for 循環中使用enumerate
來跟蹤索引,而不是使用總是找到目標的第一次出現的index
。
for counter, element in enumerate(list):
new_string = new_string + str(element)
if counter == (len(list)-2):
...
格式聲明更清晰。
這也對我有用:
def sentence(x):
if len(x) == 1:
return x[0]
return (', '.join(x[:-1])+ ' and ' + x[-1])
由於該函數必須適用於傳遞給它的所有列表值,包括整數,因此它應該能夠返回/打印所有值,即 str()。 我的完整工作代碼如下所示:
spam = ['apples', 'bananas', 'tofu', 'cats', 2]
def commacode(words):
x = len(words)
if x == 1:
print(str(words[0]))
else:
for i in range(x - 1):
print((str(words[i]) + ','), end=' ')
print(('and ' + str(words[-1])))
commacode(spam)
只是一個簡單的代碼。 我認為我們不需要在這里使用任何花哨的東西。 :p
def getList(list):
value = ''
for i in range(len(list)):
if i == len(list) - 1:
value += 'and '+list[i]
else:
value += list[i] + ', '
return value
spam = ['apples', 'bananas', 'tofu', 'cats']
print('### TEST ###')
print(getList(spam))
沒有循環,沒有連接,只有兩個打印語句:
def commalist(listname):
print(*listname[:-1], sep = ', ',end=", "),
print('and',listname[-1])
我正在閱讀同一本書並提出了這個解決方案:這允許用戶輸入一些值並從輸入中創建一個列表。
userinput = input('Enter list items separated by a space.\n')
userlist = userinput.split()
def mylist(somelist):
for i in range(len(somelist)-2): # Loop through the list up until the second from last element and add a comma
print(somelist[i] + ', ', end='')
print(somelist[-2] + ' and ' + somelist[-1]) # Add the last two elements of the list with 'and' in-between them
mylist(userlist)
例子:
用戶輸入:一二三四五輸出:一、二、三、四、五
這就是我想出的。 可能有一種更簡潔的方法來編寫它,但這應該適用於任何大小的列表,只要列表中至少有一個元素。
spam = ['apples', 'oranges' 'tofu', 'cats']
def CommaCode(list):
if len(list) > 1 and len(list) != 0:
for item in range(len(list) - 1):
print(list[item], end=", ")
print('and ' + list[-1])
elif len(list) == 1:
for item in list:
print(item)
else:
print('List must contain more than one element')
CommaCode(spam)
def sample(values):
if len(values) == 0:
print("Enter some value")
elif len(values) == 1:
return values[0]
else:
return ', '.join(values[:-1] + ['and ' + values[-1]])
spam = ['apples', 'bananas', 'tofu', 'cats']
print(sample(spam))
listA = [ 'apples', 'bananas', 'tofu' ]
def commaCode(listA):
s = ''
for items in listA:
if items == listA [0]:
s = listA[0]
elif items == listA[-1]:
s += ', and ' + items
else:
s += ', ' + items
return s
print(commaCode(listA))
那一個贏得了簡單的海因。
只是,作者指定:
“您的函數應該能夠處理傳遞給它的任何列表值。”
要伴隨非字符串,請將str()
標記添加到所有 [i] 函數。
spam = ['apples', 'bananas', 'tofu', 'cats', 'bears', 21]
def pList(x):
for i in range(len(x) - 2):
print(str(x[i]) + ', ', end='')
print(str(x[-2]) + ' and ' + str(x[-1]))
pList(spam)
我是一個相當新的pythonista。 在問題中,有人要求該函數以本論壇中其他解決方案“打印”它的格式將列表內容作為字符串返回。 以下是(在我看來)這個問題的更清潔的解決方案。
這說明了 Automate The Boring Stuff 中第 4 章 [Lists] 的逗號代碼解決方案。
def comma_code(argument):
argument_in_string = ''
argument_len = len(argument)
for i in range(argument_len):
if i == (argument_len - 1):
argument_in_string = argument_in_string + 'and ' + argument[i]
return argument_in_string
argument_in_string = argument_in_string + argument[i] + ', '
spam = ['apples', 'bananas', 'tofu', 'cats']
return_value = comma_code(spam)
print(return_value)"
我想出了這個解決方案
#This is the list which needs to be converted to String
spam = ['apples', 'bananas', 'tofu', 'cats']
#This is the empty string in which we will append
s = ""
def list_to_string():
global spam,s
for x in range(len(spam)):
if s == "":
s += str(spam[x])
elif x == (len(spam)-1):
s += " and " + str(spam[x])
else:
s += ", " + str(spam[x])
return s
a = list_to_string()
print(a)
由於沒有提到,這里有一個 f 字符串的答案,供參考:
def list_things(my_list):
print(f'{", ".join(my_list[:-1])} and {my_list[-1]}.')
一個插入自定義消息並接受字符串作為參數的示例:
def like(my_animals = None):
message = 'The animals I like the most are'
if my_animals == None or my_animals == '' or len(my_animals) == 0:
return 'I don\'t like any animals.'
elif len(my_animals) <= 1 or type(my_animals) == str:
return f'{message} {my_animals if type(my_animals) == str else my_animals[0]}.'
return f'{message} {", ".join(my_animals[:-1])} and {my_animals[-1]}.'
>>> like()
>>> like('')
>>> like([])
# 'I don't like any animals.'
>>> like('unicorns')
>>> like(['unicorns'])
# 'The animals I like the most are unicorns.'
>>> animals = ['unicorns', 'dogs', 'rabbits', 'dragons']
>>> like(animals)
# 'The animals I like the most are unicorns, dogs, rabbits and dragons.'
我對任何解決方案都不滿意,因為沒有一個解決方案可以處理or
,例如apples, bananas, or berries
def oxford_comma(words, conjunction='and'):
conjunction = ' ' + conjunction + ' '
if len(words) <= 2:
return conjunction.join(words)
else:
return '%s,%s%s' % (', '.join(words[:-1]), conjunction, words[-1])
否則,此解決方案或多或少與@PM2Ring 提供的解決方案相同
無論列表中的數據類型是什么,boolean、int、string、float 等,此代碼都有效。
def commaCode(spam):
count = 0
max_count = len(spam) - 1
for x in range(len(spam)):
if count < max_count:
print(str(spam[count]) + ', ', end='')
count += 1
else:
print('and ' + str(spam[max_count]))
spam1 = ['cat', 'bananas', 'tofu', 'cats']
spam2 = [23, '', True, 'cats']
spam3 = []
commaCode(spam1)
commaCode(spam2)
commaCode(spam3)
def listall(lst): # everything "returned" is class string
if not lst: # equates to if not True. Empty container is always False
return 'NONE' # empty list returns string - NONE
elif len(lst) < 2: # single value lists
return str(lst[0]) # return passed value as a string (do it as the element so
# as not to return [])
return (', '.join(str(i) for i in lst[:-1])) + ' and ' + str(lst[-1])
# joins all elements in list sent, up to last element, with (comma, space)
# AND coverts all elements to string.
# Then inserts "and". lastly adds final element of list as a string.
這不是為了回答最初的問題。 這是為了展示如何定義解決本書要求的所有問題的函數,而不是復雜的。 我認為這是可以接受的,因為原始問題發布了書籍“逗號代碼”測試。 重要提示:我發現可能對其他人有所幫助的令人困惑的事情是。 “列表值”表示列表類型的值或“整個列表”,它並不表示“列表類型”中的單個值(或切片)。 希望這會有所幫助
以下是我用來測試它的樣本:
empty = []
ugh = listall(empty)
print(type(ugh))
print(ugh)
test = ['rabbits', 'dogs', 3, 'squirrels', 'numbers', 3]
ughtest = listall(test)
print(type(ughtest))
print(ughtest)
supertest = [['ra', 'zues', 'ares'],
['rabbit'],
['Who said', 'biscuits', 3, 'or', 16.71]]
one = listall(supertest[0])
print(type(one))
print(one)
two = listall(supertest[1])
print(type(two))
print(two)
last = listall(supertest[2])
print(type(last))
print(last)
我沒有深入研究所有答案,但我確實看到有人建議使用 join。 我同意,但由於在學習加入之前這個問題沒有出現在書中,所以我的答案是這樣的。
def To_String(my_list)
try:
for index, item in enumerate(my_list):
if index == 0: # at first index
myStr = str(item) + ', '
elif index < len(my_list) - 1: # after first index
myStr += str(item) + ', '
else:
myStr += 'and ' + str(item) # at last index
return myStr
except NameError:
return 'Your list has no data!'
spam = ['apples', 'bananas', 'tofu', 'cats']
my_string = To_String(spam)
print(my_string)
結果:
apples, bananas, tofu, and cats
首先,我在做 python 和一般編碼方面只有兩個月的時間。
這需要 2 小時以上的時間來解決,因為我將空列表變量作為 lst = [],而不是使用 lst = "" ......還不知道為什么。
user_input = input().split()
lst = "" # I had this as lst = [] but doesn't work I don't know why.... yet
for chars in user_input:
if chars == user_input[0]:
lst += user_input[0]
elif chars == user_input[-1]:
lst += ", and " + chars
else:
lst += ", " + chars
print(lst)
.split() 函數會將我們的用戶輸入(字符串值)放入一個列表中。 這給了我們索引,我們可以使用我們的 for 循環。 第一個空字符串變量仍在進行中的理解。 接下來,在我們的 for 循環中查看每個索引,如果該索引與我們的布爾值匹配,我們將我們想要的內容添加到列表中。 在這種情況下, none 或 a ,或者最后只是另一個, (comma) 。 然后打印。
也就是說,大多數答案都包含 .join 方法,但在本書的這一部分,沒有談到這一點。 這是第六章
基本上這就像我教你加減法然后給你一個分數測試。 我們還沒有准備好,只是混淆了,至少對我來說是這樣。 更不用說甚至沒有人提供有關它的文檔。 .join() 方法如果有人需要,可以在此處查看文檔和示例的幾個區域:
#PayItForward
edgecase = []
edgecase2 = ['apples','bananas']
supplies = ['pens','staples','flamethrowers','binders']
def list2string(list):
string = ''
for index, value in enumerate(list):
if len(list) == 1:
string = value
elif index == len(list)-2:
string += value + ' '
elif index < len(list)-2:
string += value + ',' + ' '
else:
string += 'and ' + value
return string
print(list2string(supplies))
print(list2string(edgecase))
print(list2string(edgecase2))
: pens, staples, flamethrowers and binders
:
: apples and bananas
在了解了一些 about.join 之后,這是我實現它的方式
def commaCode(list):
strList = (', '.join(list[:-1]))
lastItem = (''.join(list[-1]))
print(f"{strList}, and {lastItem}")
pets = ['perrot', 'fish', 'dog', 'cat', 'hamster']
commaCode(pets)
commaCode(pets[:3])
Output:
perrot, fish, dog, cat, and hamster
perrot, fish, and dog
這就是我所做的,IMO 它更直觀......
spam = ['apples','bananas','tofu','cats']
def ipso(x):
print("'" , end="")
def run (x):
for i in range(len(x)):
print(x[i]+ "" , end=',')
run(x)
print("'")
ipso(spam)
為什么每個人都輸入如此復雜的代碼。
請參閱下面的代碼。 即使對於初學者來說,它也是最簡單和最容易理解的。
import random
def comma_code(subject):
a = (len(list(subject)) - 1)
for i in range(0, len(list(subject))):
if i != a:
print(str(subject[i]) + ', ', end="")
else:
print('and '+ str(subject[i]))
spam = ['apples','banana','tofu','cats']
完成上述編碼后,只需在 python shell 中輸入 comma_code(spam) 即可。 享受
def commacode(mylist):
mylist[-1] = 'and ' + mylist[-1]
mystring = ', '.join(mylist)
return mystring
spam = ['apple', 'bananas', 'tofu', 'cats']
print commacode(spam)
spam=['apples','bananas','tofu','cats']
print("'",end="")
def val(some_parameter):
for i in range(0,len(spam)):
if i!=(len(spam)-1):
print(spam[i]+', ',end="")
else:
print('and '+spam[-1]+"'")
val(spam)
這是我的解決方案。 一旦我找到了 join 方法以及它是如何工作的,剩下的就跟着來了。
spam = ['apples', 'bananas', 'tofu', 'cats']
def commas(h):
s = ', '
print(s.join(spam[0:len(spam)-1]) + s + 'and ' + spam[len(spam)-1])
commas(spam)
mijn_lijst = ['tafel', 'stoel', 'bank', 'tv-meubel']
def comma_code(verander):
nieuwe_lijst = ''
for i in verander[0:-1]:
x = nieuwe_lijst = nieuwe_lijst + f'{i}, '
x = x + f' and {mijn_lijst[-1]}'
return x
print(comma_code(mijn_lijst))
spam=['apple', 'banana', 'tofu','cats']
spam[-1]= 'and'+' '+ spam[-1]
print (', '.join((spam)))
目前正在按照這本初學者的書進行操作,並且已經完成了一個實踐項目“逗號代碼”,該項目要求用戶構建一個程序,該程序應:
以列表值作為參數,並返回一個字符串,其中所有項目用逗號和空格分隔,最后一個項目之前帶有,並插入該項目。 例如,將下面的垃圾郵件列表傳遞給該函數將返回“蘋果,香蕉,豆腐和貓”。 但是您的函數應該能夠處理傳遞給它的任何列表值。
spam = ['apples', 'bananas', 'tofu', 'cats']
我對這個問題的解決方案(可以很好地工作):
spam= ['apples', 'bananas', 'tofu', 'cats']
def list_thing(list):
new_string = ''
for i in list:
new_string = new_string + str(i)
if list.index(i) == (len(list)-2):
new_string = new_string + ', and '
elif list.index(i) == (len(list)-1):
new_string = new_string
else:
new_string = new_string + ', '
return new_string
print (list_thing(spam))
我唯一的問題是,有什么方法可以縮短代碼? 還是使其更具“ pythonic”性?
這是我的代碼。
def listTostring(someList):
a = ''
for i in range(len(someList)-1):
a += str(someList[i])
a += str('and ' + someList[len(someList)-1])
print (a)
spam = ['apples', 'bananas', 'tofu', 'cats']
listTostring(spam)
輸出:蘋果,香蕉,豆腐和貓
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.