将列表值与dict值进行比较

时间:2015-01-16 02:08:12

标签: python

我有一个类似于

的列表
myList = ['county name', 'state name', 'name of county seat'],
          ['county name', 'state name', 'name of county seat']

和一个dict,状态名称为键,状态缩写为值。

state_names = {'alabama': 'AL', ...}

我试图弄清楚如何遍历myList并返回匹配状态的缩写。

我试过了:

for entry in myList:
    state_name = entry[1].lower()
    for key in state_lookup.stateNames:
        if state_name == key:
            return state_lookup.stateNames[key]

由于我确信其他人很明显的原因,这项工作无效。

4 个答案:

答案 0 :(得分:3)

这通常不是您希望拥有的那种数据结构,您应该拥有某种嵌套结构。因此,正确的答案包括改变从中获取数据的位置,以这种方式为您提供数据(元组列表)。

但如果你拥有的是什么,那么你需要grouper recipe from the itertools documentation或使用你的数据[1 :: 3]来分割你的州名,然后你可以写一个列表理解抬头看。

答案 1 :(得分:2)

您可以使用3的步幅切片列表

如果找不到密钥,使用get()可以使用默认值。在这种情况下,我使用key作为默认值。

[state_lookup.stateNames.get(key.lower(), key) for key in myList[1::3]]

您可能更喜欢跳过缺失的密钥

state_names  = state_lookup.stateNames
[state_names[key.lower()] for key in myList[1::3] if key.lower() in state_names]

它会简化代码,将三元组分组为元组 - 例如。

myList = [('county name', 'state name', 'name of county seat'),
          ('county name', 'state name', 'name of county seat'),
          ]

然后你可能会得到像

这样的东西
[state_lookup.stateNames.get(key[1].lower(), key) for key in myList]

答案 2 :(得分:1)

你可以这样做:

abbrevs = [state_lookup.stateNames.get(name.lower(), None) 
           for i, name in enumerate(my_list) if i % 3 == 1]

答案 3 :(得分:0)

使用现有的实施

您当前的代码示例不起作用,因为它始终只返回myList中第一个状态的缩写。

示例:

myList = [['Montgomery', 'Ohio', 'Dayton'], ['Fayette', 'Kentucky', 'Lexington']]

for entry in myList:
    #1st iteration, entry = ['Montgomery', 'Ohio', 'Dayton']
    state_name = entry[1].lower()
    #1st iteration, state_name = 'ohio'
    for key in state_lookup.stateNames: 
    #not sure what state_lookup.stateNames is doing here...?
        if state_name == key:
        #loop will iterate until key gets to 'ohio' entry
            return state_lookup.stateNames[key]
            #'OH' abbreviation returned assuming that 
            #state_lookup.stateNames is a dict

您可能会发现使用生成器执行此操作非常有用:

def state_abbr_from_CoStSeats(co_st_seats, state_lookup_dict):
    for co_st_seat in co_st_seats:
        yield state_lookup_dict[lower(co_st_seat)]
        #using yield instead of return creates a generator

现在您可以从生成器中获取缩写列表:

my_abbr_list = list(def state_abbr_from_CoStSeats(myList, state_lookup))

或者,您可以编写一个从列表项中获取缩写的函数:

def state_abbr_from_CoStSeat(co_st_seat, state_lookup):
    return state_lookup[lower(co_st_seat[1])]

然后列出缩写:

my_abbr_list =[state_abbr_from_CoStSeat(item, state_lookup) for item in myList]

使用替代实施

由于县名,州名和县城名称可能不会经常更改,我建议您放弃嵌套列表并使用collections.namedtuple代替。

示例:

from collections import namedtuple
CoStSeat = namedtuple('CoStSeat','county state seat')

现在你可以这样做:

item = CoStSeat(state = 'Kentucky', county = 'Fayette', seat = 'Lexington')

而且:

assert item['state'] == 'Kentucky'

填充myList可能是这样的:

myList = []
iterable_items = <---some kind of iterable input-->
#the iterable input can be something like your nested lists or nested tuples 
#or even some kind of an input file
#
#this will work as long as your iterable_items object is in the form:
#    [[county, state, seat], ...] or 
#    [(county, state, seat], ...] or
#    {(county, state, seat], ...} 
for item in iterable_items: 
    myList.append(CoStSeat(*item))

现在你可以做这样的事情:

states_iterable = (lower(item['state']) for item in myList)
#produces a generator that spits out the lowercase states

如果你不想使用namedtuple,你可以这样做:

states_iterable = (lower(item[1]) for item in myList) 
#this is assuming 1 is the address of the state name

这会产生一个生成器,可以在for语句中使用,或者使用next() next(states_iterable)(直到结束)。

所以现在你可以使用你的生成器走过你的字典了:

myAbbrList = []
for state in states_iterable:
    myAbbrList.append(states_dict[state])

如果您愿意,可以在一行中完成所有这些操作:

my_abbr_list = [states_dict[lower(item[1]) for item in myList]

或者如果您使用的是namedtuple

my_abbr_list = [states_dict[lower(item['state']) for item in myList]