2

I have a situation where some city names need to be renamed, so I am using a dict where the keys are the old city names and the values are the new ones. However, only some cities need to be renamed so not all possible cities are in the dict.

The only way I know how to do it is to except a KeyError when the city doesn't need to be renamed, which works, but I'm not sure if this is bad practice, or if there are any downfalls to this. Is there something I am missing?

# Set Venue
venue_name = unidecode(cell[2].get_text())
try:
    # Correct venue names i.e. Cairns, QLD = Cairns
    venue_name = VENUE_NAMES_DICT[venue_name]
except KeyError:
    pass
moto
  • 946
  • 10
  • 27

5 Answers5

2

As @jarmod suggests, you can use the .get() method of the standard Dictionary to provide a default value in case the key is missing. What isn't described is that this approach enables you to turn your problem into a one-liner by passing the venue_name value to .get() as the default value.

# Set Venue
venue_name = unidecode(cell[2].get_text())
# Correct venue names i.e. Cairns, QLD = Cairns
venue_name = VENUE_NAMES_DICT.get(venue_name, venue_name)

If venue_name is present as a key in the dictionary, .get() will return the desired new value. If it isn't present, .get() will return the original value of venue_name unchanged. This eliminates the need for any conditional logic.

Craig
  • 4,605
  • 1
  • 18
  • 28
0

What you can do is use defaultdict

from collections import defaultdict
d=defaultdict(list) #this will return a empty list everytime a new key is used or if key exists it will appendt the value to the list
d[venue_name]=a

Example:

>>> from collections import defaultdict
>>> city_list = [('TX','Austin'), ('TX','Houston'), ('NY','Albany'), ('NY', 'Syracuse'), ('NY', 'Buffalo'), ('NY', 'Rochester'), ('TX', 'Dallas'), ('CA','Sacramento'), ('CA', 'Palo Alto'), ('GA', 'Atlanta')]
>>>
>>> cities_by_state = defaultdict(list)
>>> for state, city in city_list:
...     cities_by_state[state].append(city)
...
for state, cities in cities_by_state.iteritems():
...     print state, ', '.join(cities)
...
NY Albany, Syracuse, Buffalo, Rochester
CA Sacramento, Palo Alto
GA Atlanta
TX Austin, Houston, Dallas
Demonking28
  • 749
  • 7
  • 21
0

You can use "in", like this:

data = ['Chicago', 'NYC', 'Boston', 'SD']

dictionary = {'NYC': 'New York', 'SD': 'San Diego'}

new_list = []

for x in data:
    if x in dictionary:
        new_list.append(dictionary[x])
    else:
        new_list.append(x)

print(new_list)

#output

['Chicago', 'New York', 'Boston', 'San Diego']

Using List comprehension

data = ['Chicago', 'NYC', 'Boston', 'SD']
dictionary = {'NYC': 'New York', 'SD': 'San Diego'}
new_list=[dictionary[x] if x in dictionary else x for x in data]
print(new_list)


['Chicago', 'New York', 'Boston', 'San Diego']
Demonking28
  • 749
  • 7
  • 21
kjmerf
  • 4,275
  • 3
  • 21
  • 29
  • I love when people down vote and don't comment – kjmerf Jan 07 '18 at 23:41
  • It was one of the other answerers. – cs95 Jan 07 '18 at 23:43
  • @COLDSPEED it's one of my pet peeves on this site. I'm interested in feedback on any of my answers but have no idea what to do with a down vote and no comment – kjmerf Jan 07 '18 at 23:46
  • 3
    This would surprise you, but most users aren't as receptive to downvotes or feedback as you would think. Providing feedback links you to downvotes and would just encourage revenge voting. – cs95 Jan 07 '18 at 23:50
  • Apparently... It's odd that people are more interested in rep than exchanging ideas and learning, but I digress... – kjmerf Jan 07 '18 at 23:52
  • 1
    They've toyed with the idea of requiring comments with every down-vote, and this gets suggested on meta at least 5 times a week (or more), but it always gets turned down, mainly due to experience of most of us of getting bitten for posting the comments. As @cᴏʟᴅsᴘᴇᴇᴅ aptly states, most posters will only argue with the down-voter rather than be receptive to any sort of criticism to their question or answer. – Hovercraft Full Of Eels Jan 08 '18 at 00:39
  • I will mention though that your answer could use more explanation clarifying why you recommend your code, making it much more helpful to future visitors and not just the OP, and *this* could be a valid reason to down-vote it, and is in fact one of the most frequent reasons that I've down-voted answers before. – Hovercraft Full Of Eels Jan 08 '18 at 00:41
0

You can use dict.get(key, default_value) and supply a default value.

jarmod
  • 71,565
  • 16
  • 115
  • 122
-1

In general, throwing exceptions for non-exceptional situations is poor design. You want a defaultdict.

from collections import defaultdict

renames = defaultdict(lambda: None)
# Add the elements to renames here ...

Now, renames is a dictionary, except that if the key doesn't exist, it returns None rather than throwing, so you can just check if the value is None to see if it needs to be renamed.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116