我正在研究一个问题,我必须编写一个程序来计算厨师准备所需的每个项目的数量。客户可以订购的商品有:沙拉,汉堡包和水。 salad:[# salad] hamburger:[# hamburger] water:[# water]
例如If order = "hamburger water hamburger"
,然后该函数返回"salad:0 hamburger:2 water:1"
我的代码是:
def ite(order,item):
v=order.split()
t=[]
for salad in v:
if salad==item:
t.append(item)
v.remove(item)
return len (t)
def item_order(order):
s=ite(order,'salad')
h=ite(order,'hamburger')
w=ite(order,'water')
x='salad:%s hamburger:%s water:%s' %(s,h,w)
return x
但是当我们输入item_order('water water water')
时,我的程序会打印
salad:0 hamburger:0 water:2
而不是
salad:0 hamburger:0 water:3
如果没有两个连续的单词,它可以正常工作。我怎么能纠正这个?
答案 0 :(得分:4)
您可以使用collections.Counter:
from collections import Counter
def item_order(order, items=('salad', 'hamburger', 'water')):
counter = Counter(order.split())
return ' '.join(['{}: {}'.format(item, counter.get(item, 0)) for item in items])
print(item_order('water water water'))
print(item_order('water salad, salad'))
print(item_order('water hamburger'))
测试它:
print(item_order('water water water'))
print(item_order('water salad, salad'))
print(item_order('water hamburger'))
打印:
salad: 0 hamburger: 0 water: 3
salad: 1 hamburger: 0 water: 1
salad: 0 hamburger: 1 water: 1
这些项目是默认参数:
def item_order(order, items=('salad', 'hamburger', 'water')):
这使得该功能更加灵活,因为您可以根据需要提交其他项目:
def item_order(order, items=('salad', 'fruit', 'water')):
这里有意使用元组,因为列表等可变默认参数可能会导致无意的副作用。这里没问题但可能是一般的花瓶。
将白色空格处的输入字符串拆分为列表后,Counter
将创建一个新的counter
实例:
counter = Counter(order.split())
例如:
>>> Counter('water water salad'.split())
Counter({'salad': 1, 'water': 2})
最后,列表理解有助于创建一个新的字符串:
' '.join(['{}: {}'.format(item, counter.get(item, 0)) for item in items])
' '.join
从字符串列表中创建一个新字符串,其中列表元素由空格分隔。例如:
>>> ' '.join(['abc', 'xyz', 'uvw'])
'abc xyz uvw'
如果密钥在其中,Python字典的方法get()
将返回密钥的值,否则返回默认值。例如:
>>> d = {'a': 100, 'b': 200}
>>> d.get('a', 0)
100
>>> d.get('x', 0)
0
将此默认值设置为0
,为订单中未包含的项目提供零计数:
counter.get(item, 0))
最后,format()
方法有助于将计数值放在字符串中。例如:
>>> '{}: {}'.format('abc', 10)
'abc: 10'
答案 1 :(得分:2)
你不应该做
v.remove(salad)
删除该行,它将解决您的问题。
In [18]: def ite(order,item):
v=order.split()
t=[]
for salad in v:
if salad==item:
t.append(item)
return len(t)
In [19]: item_order('salad salad water')
Out[19]: 'salad:2 hamburger:0 water:1'
In [20]: item_order('salad water salad')
Out[20]: 'salad:2 hamburger:0 water:1'
In [21]: item_order('salad water hamburger')
Out[21]: 'salad:1 hamburger:1 water:1'
为什么它不能用于背靠背复制元素是因为在Python中迭代序列并不会隐式地复制列表。该列表将被修改。您可以通过v [:],
制作副本In [98]: def ite(order,item):
v=order.split()
t=[]
for salad in v[:]:
if salad==item:
t.append(item)
v.remove(item)
return len(t)
答案 2 :(得分:2)
在迭代时你不应该使用t.remove()。但为什么? 我试图模拟你的问题
t = ['a', 'b', 'c']
it = iter(it) # for loop internally use iter() to iterate
it.next() # it should print 1st element of list which is 'a'
t.remove('a') #Now list t becomes ['b', 'c']
it.next() # it should print 2nd element of list which is 'c'
t.remove('b') #Now list t becomes ['c']
it.next() #it should print 3rd element of list, But list has only one element
# It throws exception - "StopIteration"
此异常由"处理"静静地循环,所以" for"循环不会迭代第3个元素。
答案 3 :(得分:0)
在迭代它时改变列表通常是一个坏主意 - 即你删除了python已经迭代过的项目吗?
list对象有一个可能有帮助的count方法!
split_order = order.split(" ")
salads = split_order.count('salad')