简体   繁体   English

根据用户从字典中输入的信息来提取信息

[英]Extracting information depending on user input from a dictionary

I have the following information from a .json loaded and stored in a variable Data : 我从.json获取以下信息,并将其存储并存储在变量Data

Data = [
    {u'rating': u'89', u'rare': u'1', u'name': u'Pogba', u'club_image': u'/content/fifa17/img/clubs/11.png', u'image': u'/content/fifa17/img/players/195864.png', u'rare_type': u'3', u'version': u'IF', u'full_name': u'Pogba', u'position': u'CDM', u'id': u'15073', u'nation_image': u'/content/fifa17/img/nation/18.png'},
    {u'rating': u'89', u'rare': u'1', u'name': u'Pogba', u'club_image': u'/content/fifa17/img/clubs/11.png', u'image': u'/content/fifa17/img/players/195864.png', u'rare_type': u'21', u'version': u'OTW', u'full_name': u'Pogba', u'position': u'CM', u'id': u'15091', u'nation_image': u'/content/fifa17/img/nation/18.png'},
    {u'rating': u'88', u'rare': u'1', u'name': u'Pogba', u'club_image': u'/content/fifa17/img/clubs/11.png', u'image': u'/content/fifa17/img/players/195864.png', u'rare_type': u'1', u'version': u'Normal', u'full_name': u'Pogba', u'position': u'CM', u'id': u'78', u'nation_image': u'/content/fifa17/img/nation/18.png'}
]

I'd like to extract the information depending on the rating of the player inputted by the user, only if another rating exists . 我想根据用户输入的玩家rating来提取信息,前提是存在另一个评分 EDIT : By this, I mean that if only one line was present, ie 1 rating, there would be no need to carry out the process. 编辑通过这个,我的意思是,如果只显示一行,即1个等级,则无需执行该过程。

For example, if the user inputted: 88 , it would return/print: 例如,如果用户输入: 88 ,它将返回/打印:

{u'rating': u'88', u'rare': u'1', u'name': u'Pogba', u'club_image': u'/content/fifa17/img/clubs/11.png', u'image': u'/content/fifa17/img/players/195864.png', u'rare_type': u'1', u'version': u'Normal', u'full_name': u'Pogba', u'position': u'CM', u'id': u'78', u'nation_image': u'/content/fifa17/img/nation/18.png'}

From my minimal knowledge, I am aware that I must use dictionaries, but am unaware of how to do so. 据我所知,我知道我必须使用字典,但不知道如何使用字典。 However, I am currently in the following stage in my attempts: 但是,我目前正处于以下尝试阶段:

player_dict = {Data}
player_info = player_dict.get(user_input)
if player_info:
    for item in player_info:
        player_info = item

^ This doesn't seem to work at all. ^ 这似乎根本不起作用。

Well in this case, you need to loop over your values and compare the one that has been input to the ones you already have, right? 好吧,在这种情况下,您需要遍历您的值,并将输入的值与您已有的值进行比较,对吗?

So player_dict is a list of dictionaries, and every dictionary contains properties about a player, of which rating is one. 因此player_dict是词典的列表,每本词典都包含有关玩家的属性,其中rating为1。 Also, let's say that player_info is the user-inputted rating, like 88 . 另外,假设player_info是用户输入的评分,例如88

for player_dict in player_dict:
    try:
         if player_dict['rating']==player_info:
              return player_dict
    except KeyError:
         print 'there is no key called rating in this dict!'

You can use list comprehensions: 您可以使用列表推导:

[record for record in Data if record.get("rating") == ratingWeWant]

where ratingWeWant is the rating you are searching for. 其中ratingWeWant是您要搜索的评分。

That code will produce list of records from data that have specified rating, eg: 该代码将根据具有指定等级的数据生成记录列表,例如:

[{u'rating': u'88', u'club_image': u'/content/fifa17/img/clubs/11.png', u'image': u'/content/fifa17/img/players/195864.png', u'full_name': u'Pogba', u'id': u'78', u'nation_image': u'/content/fifa17/img/nation/18.png', u'rare': u'1', u'name': u'Pogba', u'rare_type': u'1', u'version': u'Normal', u'position': u'CM'}]

for data in your post. 在您的帖子中获取数据。

Also, because we use .get() method of dict, we don't have to worry about exceptions. 另外,因为我们使用dict的.get()方法,所以我们不必担心异常。

What you are trying to do is called a "lookup". 您尝试执行的操作称为“查找”。 Given a key (u'88', or other rating), you want a value (the dictionary where 'rating' is u'88'). 给定键(u'88'或其他评级),您需要一个值('rating'为u'88'的字典)。 A list object, like you currently have the dictionaries stored in, is not very good for such lookups, because you have to go through each index in the list, compare the rating to the key, and then return the dictionary (if it exists at all). 列表对象(例如您当前存储有字典)对于这种查找不是很好,因为您必须遍历列表中的每个索引,将等级与关键字进行比较,然后返回字典(如果字典存在于所有)。

key = u'88'
for d in Data:
    if d['rating'] == key:
        print d

Consider what happens when you have a large amount of dictionaries stored in that list. 考虑一下当该列表中存储了大量词典时会发生什么。 What if none of the dictionaries have a rating equal to the key? 如果没有一个字典的评价等于该键怎么办? You pass through a large number of dictionaries, checking for equalities, only to have none exist. 您通过大量词典​​,检查是否相等,只有一个不存在。 This is wasted computations. 这浪费了计算。

As you know, python's dict type is very-well suited for lookups. 如您所知,python的dict类型非常适合查找。 If you had a dictionary that looked like 如果您有一本看起来像的字典

Data_dict = {u'88': {u'rare': u'1', u'name': u'Pogba', ...},
             u'89': {u'rare': u'1', u'name': u'Pogba', ...} }

then you could quickly see if the key u'88' is in that dataset. 那么您可以快速查看键u'88'是否在该数据集中。

if u'88' in Data_dict:
    print Data_dict[u'88']

To make such a dictionary, from your current Data as a list: 要制作这样的字典,请从您当前的数据列表中:

Data_dict = {val[u'rating']: val for val in Data}

The other answers don't include your requirement that data should only be returned if the rating appears in Data once only. 其他答案不包括您的要求,即仅当rating一次出现在“ Data ,才应返回Data

# First iterate over Data and count how many times that rating appears
counter = {}
for item in Data:
    rating = item['rating']
    counter[rating] = counter.get(rating, 0) + 1

# Now build a dict that uses rating as a key and the whole dataset with  
# that rating as a value. Include only ratings that appeared once in Data
cleaned_dict = {item['rating']: item for item in Data if counter.get(item['rating']) == 1}

query = raw_input('Enter rating:')

if cleaned_dict.get(query):
    print "FOUND"
    print cleaned_dict.get(query)
else:
    print "Not found, no need to process further"

Explanation: 说明:
In the first for loop, we build a dictionary of {rating: frequency} . 在第一个for循环中,我们构建了{rating: frequency}的字典。 The line counter[rating] = counter.get(rating, 0) + 1 says that if the rating isn't in the dictionary, give that rating a default count of 0 and immediately add 1 to it. counter[rating] = counter.get(rating, 0) + 1这行表示如果该rating不在词典中,则给该等级默认计数0然后立即将其加1 ie it appears once. 即它出现一次。 If, however, later in the for loop we find that rating again, we get the value stored against that rating and add 1 to it. 但是,如果稍后在for循环中再次找到该额定值,则将针对该额定值存储的值加上1 You could also use the Counter object for this but I've found that usually to be slower to get() . 您也可以为此使用Counter对象,但是我发现通常get()要慢一些。

In cleaned_dict we use a dictionary comprehension to build a new set of data only if that rating appeared once in Data . cleaned_dict ,仅当该等级一次出现在Data ,我们才使用字典理解来构建新的数据集。 We store the whole raw data against a key of just the rating . 我们只按rating键存储整个原始数据。 This allows fast lookup on user input. 这样可以快速查找用户输入。

Finally, we take user input and look for the rating in our dictionary. 最后,我们接受用户输入,并在字典中查找等级。 If the rating is not a key in cleaned_data then we get None , which is falsey, so if cleaned_dict.get(query): is interpreted as False . 如果等级不是cleaned_data的关键,那么我们得到None ,这是错误的,因此, if cleaned_dict.get(query):被解释为False

EDIT based on comments: 根据评论进行编辑:

cleaned_dict = {}
for item in Data:
    rating = item['rating']
    is_in_dict = cleaned_dict.get(rating)
    if is_in_dict:
        position = item['position']
        cleaned_dict[rating][position] = item
    else:
        sub_dict = {}
        sub_dict[item['position']] = item
        cleaned_dict[rating] = sub_dict

rating_input = raw_input('Enter rating:')
check_rating = cleaned_dict.get(rating_input)
if check_rating:
    position_input = raw_input('Enter position:')
    if check_rating.get(position_input):
        print check_rating.get(position_input)
    else:
        print "Record of rating, but not position"
else:
    print "No record of rating {}".format(rating_input)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM