使用地图(但不使用lambda)更新字典列表中的字典值

时间:2019-06-24 16:45:27

标签: python dictionary

我在训练营准备课程中遇到了问题。问题是让我使用一个以字典作为参数的函数,检查键之一的值的类型,然后在满足条件的情况下更新该值。当从字典列表中给定特定的列表元素时,此功能非常有用。

当我尝试将此函数嵌套到地图中以将该函数应用于整个词典列表而不是传入一个特定元素时,麻烦就来了。

我已经尝试过将函数作为第一个不带括号的map参数,如先前材料中向我展示的那样,然后我尝试将迭代器设置为不带索引的字典的基本列表,例如[ :]切片,作为[0:len {list)]切片,作为[0:2]切片,都无济于事。

# list of dictionaries to be updated, trimmed to 3 for brevity

restaurants = [{'name': 'Fork & Fig',
  'price': '$$',
  'is_closed': False,
  'review_count': 610},
 {'name': 'Salt And Board',
  'price': '$$',
  'is_closed': False,
  'review_count': 11},
 {'name': 'Stripes Biscuit',
  'price': '$$',
  'is_closed': True,
  'review_count': 20}] 

#function in question, changes the $ strings to numbers

def format_restaurant(restaurant): 
    if type(restaurant['price']) == str:
        restaurant['price'] = len(restaurant['price'])
    return restaurant 

# inputting a single dictionary entry works great:

format_restaurant(restaurants[1]) # {'is_closed': False, 'name': 'Fork & Fig', 'price': 2, 'review_count': 610}

# Here comes the sticking point. The directions are: 
#"Now write another function called map_format_restaurants using map, that 
# uses above function and returns a list of restaurants with each of them 
# formatted with price pointing to the respective number."

# My answer that I think should work, but doesn't:

def map_format_restaurants(restaurants):
    map(format_restaurant, restaurants)
    return restaurants

# When this function is called, the list of dictionaries comes out just as it went in:

map_format_restaurants(restaurants)

我希望代码将字典列表中每个“价格”键值的“ $”更改为1或将“ $$”更改为2,但它们均未更改。没有错误消息被抛出。

查看列表中的最后一个dict条目:

 {'name': 'Stripes Biscuit',
  'price': '$$',
  'is_closed': True,
  'review_count': 20}] 

应更改为:

 {'name': 'Stripes Biscuit',
  'price': 2,
  'is_closed': True,
  'review_count': 20}] 

但是就像进去一样出来了。

我确定这对那里的某人来说是个不错的垒球,但我似乎无法击中它。任何见解将不胜感激。

2 个答案:

答案 0 :(得分:2)

在Python 3中,map是一个惰性生成器。它仅在您使用该函数(即当您要求其提供元素)时才运行该函数。在此之前,它只是作为map对象坐在那里,等待。

一种消耗map的相当标准的方法是从其构建list

def map_format_restaurants(restaurants):
    return list(map(format_restaurant, restaurants))

请记住,这将创建一个全新的列表,但也会就地修改现有列表。这意味着您不需要建立新列表,并且可以使用我所知道的最快方法,如果只使用迭代器来产生副作用的话:

from collections import deque

deque(map(format_restaurant, restaurants), maxlen=0)

maxlen参数可确保deque在消耗迭代器时保持为空。

但是,鉴于您正在就地修改所有内容,因此format_restaurant的返回值有些不可思议。我建议使用一个简单的for循环:

def format_restaurant(restaurant):
    ...
    # no return value

for restaurant in restaurants:
     format_restaurant(restaurant)

答案 1 :(得分:-1)

map()建立一个新列表。它修改现有列表。因此,将您的功能修改为:

def map_format_restaurants(restaurants):
    return map(format_restaurant, restaurants)

类似地,您需要从该函数分配返回值:

new_restaurants = map_format_restaurants(restaurants)