我对Python很新,但我没有找到这个特定问题的答案。 我正在写一个简单的推荐计划,我需要一本字典,其中菜肴是一个关键,餐厅的名称是一个价值。在一些情况下,我必须拆分一些美食名称的字符串,并确保所有其他餐厅(价值观)具有相同的美食被分配到相同的美食(关键)。这是文件的一部分:
getSelection()
因此它只是第一个和最后一个具有相同的美食,但文件后面还有更多。 这是我的代码:
Georgie Porgie
87%
$$$
Canadian, Pub Food
Queen St. Cafe
82%
$
Malaysian, Thai
Mexican Grill
85%
$$
Mexican
Deep Fried Everything
52%
$
Pub Food
它会打印所有键和值,但不会将两个值分配给应该使用的相同键。此外,在最后一个'else'语句中,第二个餐馆被分配给错误的密钥作为第二个值。这不应该发生。我将不胜感激任何评论或帮助。
答案 0 :(得分:1)
如果只有一个类别,则不检查密钥是否在字典中。您应该像多个类别一样类似地执行此操作,然后它可以正常工作。
当你有一个文件被覆盖时,我不知道为什么你有文件作为参数。
此外,你应该做出关键的'对于每个结果,而不是+ =(将其添加到现有的'键'
当你检查j是否在字典中时,干净的方法是检查j是否在键中(d.keys())
def new(file):
file = "/.../Restaurants.txt"
d = {}
key = []
with open(file) as file:
lines = file.readlines()
for i in range(len(lines)):
if i % 5 == 0:
if "," not in lines[i + 3]:
if lines[i + 3] not in d.keys():
d[lines[i + 3].strip()] = [lines[i].strip()]
else:
d[lines[i + 3]].append(lines[i].strip())
else:
key = (lines[i + 3].strip().split(', '))
for j in key:
if j not in d.keys():
d[j] = [lines[i].strip()]
else:
d[j].append(lines[i].strip())
return d
答案 1 :(得分:0)
通常情况下,我发现如果您使用字典键的名称,以后可能会更容易处理它们。
在下面的例子中,我返回一系列字典,每个餐厅一个。我还在名为add_value()的方法中包含处理值的功能,以使代码更具可读性。
在我的示例中,我使用编解码器来解码值。虽然没有必要,但根据您正在处理的字符,它可能会有用。我也使用itertools用迭代器读取文件行。同样,根据具体情况没有必要,但如果您处理的是非常大的文件,则可能会有用。
import copy, itertools, codecs
class RestaurantListParser(object):
file_name = "restaurants.txt"
base_item = {
"_type": "undefined",
"_fields": {
"name": "undefined",
"nationality": "undefined",
"rating": "undefined",
"pricing": "undefined",
}
}
def add_value(self, formatted_item, field_name, field_value):
if isinstance(field_value, basestring):
# handle encoding, strip, process the values as you need.
field_value = codecs.encode(field_value, 'utf-8').strip()
formatted_item["_fields"][field_name] = field_value
else:
print 'Error parsing field "%s", with value: %s' % (field_name, field_value)
def generator(self, file_name):
with open(file_name) as file:
while True:
lines = tuple(itertools.islice(file, 5))
if not lines: break
# Initialize our dictionary for this item
formatted_item = copy.deepcopy(self.base_item)
if "," not in lines[3]:
formatted_item['_type'] = lines[3].strip()
else:
formatted_item['_type'] = lines[3].split(',')[1].strip()
self.add_value(formatted_item, 'nationality', lines[3].split(',')[0])
self.add_value(formatted_item, 'name', lines[0])
self.add_value(formatted_item, 'rating', lines[1])
self.add_value(formatted_item, 'pricing', lines[2])
yield formatted_item
def split_by_type(self):
d = {}
for restaurant in self.generator(self.file_name):
if restaurant['_type'] not in d:
d[restaurant['_type']] = [restaurant['_fields']]
else:
d[restaurant['_type']] += [restaurant['_fields']]
return d
然后,如果你跑:
p = RestaurantListParser()
print p.split_by_type()
你应该得到:
{
'Mexican': [{
'name': 'Mexican Grill',
'nationality': 'undefined',
'pricing': '$$',
'rating': '85%'
}],
'Pub Food': [{
'name': 'Georgie Porgie',
'nationality': 'Canadian',
'pricing': '$$$',
'rating': '87%'
}, {
'name': 'Deep Fried Everything',
'nationality': 'undefined',
'pricing': '$',
'rating': '52%'
}],
'Thai': [{
'name': 'Queen St. Cafe',
'nationality': 'Malaysian',
'pricing': '$',
'rating': '82%'
}]
}
您的解决方案很简单,所以没关系。我想提一下当我想到这类问题时想到的一些想法。
答案 2 :(得分:0)
这是另一种用法,使用defaultdict和split简化了事情。
p4 revert