Python Programming - to modify a list item in a dictionary - python

Question: # Write a program to modify the email addresses in the records dictionary to reflect this change
records = {57394: ['Suresh Datta', 'suresh#example.com'], 48539: ['ColetteBrowning', 'colette#example.com'], 58302: ['Skye Homsi','skye#example.com'], 48502: ['Hiroto Yamaguchi', 'hiroto#example.com'], 48291: ['Tobias Ledford', 'tobias#example.com'], 48293: ['Jin Xu', 'jin#example.com'], 23945: ['Joana Dias', 'joana#example.com'], 85823: ['Alton Derosa', 'alton#example.com']}
I have iterated through the dictionary and created a new list with the values and split the email at # and was able to change the the email from .com to .org.
My approach was to join the changed email and change the values of the dictionary. However, I keep on getting a TypeError: sequence item 0: expected str instance, list found
my code :
lst2 = []
for value in records.values():
lst2.append(value[1].split('#'))
for items in lst2:
items[1] = 'examples.org'
for items in lst2:
','.join(lst2)

The issue is in your final for loop:
for items in lst2:
','.join(lst2)
You are joining should be joining items not lst2. However if you fix that it still won't work. You need to create a third list and add the values to it like this:
lst3 = []
for items in lst2:
lst3.append('#'.join(items))
Then, lst3 will have the properly formatted emails.

You can do a one-liner list-comprehension for, then iterate and do join the split of i with ',', so try this:
print([','.join(i[1].replace('.com','.org').split('#')) for i in records.values()])
Output:
['suresh,example.org', 'colette,example.org', 'skye,example.org', 'hiroto,example.org', 'tobias,example.org', 'jin,example.org', 'joana,example.org', 'alton,example.org']
Or:
print(['#'.join(i[1].replace('.com','.org').split('#')) for i in records.values()])
Output:
['suresh#example.org', 'colette#example.org', 'skye#example.org', 'hiroto#example.org', 'tobias#example.org', 'jin#example.org', 'joana#example.org', 'alton#example.org']
Or if want to edit dict:
print({k:[i.replace('.com','.org') for i in v] for k,v in records.items()})
Output:
{57394: ['Suresh Datta', 'suresh#example.org'], 48539: ['ColetteBrowning', 'colette#example.org'], 58302: ['Skye Homsi', 'skye#example.org'], 48502: ['Hiroto Yamaguchi', 'hiroto#example.org'], 48291: ['Tobias Ledford', 'tobias#example.org'], 48293: ['Jin Xu', 'jin#example.org'], 23945: ['Joana Dias', 'joana#example.org'], 85823: ['Alton Derosa', 'alton#example.org']}

Try the following code
records = {57394: ['Suresh Datta', 'suresh#example.com'], 48539: ['ColetteBrowning', 'colette#example.com'], 58302: ['Skye Homsi','skye#example.com'], 48502: ['Hiroto Yamaguchi', 'hiroto#example.com'], 48291: ['Tobias Ledford', 'tobias#example.com'], 48293: ['Jin Xu', 'jin#example.com'], 23945: ['Joana Dias', 'joana#example.com'], 85823: ['Alton Derosa', 'alton#example.com']}
for key, value in records.items():
new_data = []
for data in value:
new_data.append(data.replace('.com', '.org'))
records[key] = new_data
print(records)
{57394: ['Suresh Datta', 'suresh#example.org'], 48539: ['ColetteBrowning', 'colette#example.org'], 58302: ['Skye Homsi', 'skye#example.org'], 48502: ['Hiroto Yamaguchi', 'hiroto#example.org'], 48291: ['Tobias Ledford', 'tobias#example.org'], 48293: ['Jin Xu', 'jin#example.org'], 23945: ['Joana Dias', 'joana#example.org'], 85823: ['Alton Derosa', 'alton#example.org']}

Related

Combining lists within a nested list, if lists contain the same element?

I have nested list that has a structure similar to this, except it's obviously much longer:
mylist = [ ["Bob", "12-01 2:30"], ["Sal", "12-01 5:23"], ["Jill", "12-02 1:28"] ]
My goal is to create another nested lists that combines all elements that have the same date. So, the following output is desired:
newlist = [ [["Bob", "12-01 2:30"], ["Sal", "12-01 5:23"]], [["Jill", "12-02 1:28"]] ]
Above, all items with the date 12-01, regardless of time, are combined, and all elements of 12-02 are combined.
I've sincerely been researching how to do this for the past 1 hour and can't find anything. Furthermore, I'm a beginner at programming, so I'm not skilled enough to try to create my own solution. So, please don't think that I haven't attempted to do research or put any effort into trying this problem myself. I'll add a few links as examples of my research below:
Collect every pair of elements from a list into tuples in Python
Create a list of tuples with adjacent list elements if a condition is true
How do I concatenate two lists in Python?
Concatenating two lists of Strings element wise in Python without Nested for loops
Zip two lists together based on matching date in string
How to merge lists into a list of tuples?
Use dict or orderdict(if the sort is important) group data by the date time .
from collections import defaultdict # use defaultdict like {}.setdefault(), it's very facility
mylist = [["Bob", "12-01 2:30"], ["Sal", "12-01 5:23"], ["Jill", "12-02 1:28"]]
record_dict = defaultdict(list)
# then iter the list group all date time.
for data in mylist:
_, time = data
date_time, _ = time.split(" ")
record_dict[date_time].append(data)
res_list = list(record_dict.values())
print(res_list)
output:
[[['Bob', '12-01 2:30'], ['Sal', '12-01 5:23']], [['Jill', '12-02 1:28']]]
A pure list-based solution as an alternative to the accepted dictionary-based solution. This offers the additional feature of easily sorting the whole list, first by date, then by hour, then by name
from itertools import groupby
mylist = [["Bob", "12-01 2:30"], ["Sal", "12-01 5:23"], ["Jill", "12-02 1:28"]]
newlist = [dt.split() + [name] for (name, dt) in mylist]
newlist.sort() # can be removed if inital data is already sorted by date
newlist = [list(group) for (date, group) in groupby(newlist, lambda item:item[0])]
# result:
# [[['12-01','2:30','Bob'], ['12-01','5:23','Sal']], [['12-02','1:28','Jill']]]
If you really want the same item format as the initial list, it requires a
double iteration:
newlist = [[[name, date + ' ' + time] for (date, time, name) in group]
for (date, group) in groupby(newlist, lambda item:item[0])]
# result:
# [[['Bob', '12-01 2:30'], ['Sal', '12-01 5:23']], [['Jill', '12-02 1:28']]]
If you don't mind going heavy on your memory usage, you can try using a dictionary. You can use the date as the key and make a list of values.
all_items = {}
for line in myList:
x, y = line
date, time = y.split()
try:
all_items[date].append(line)
except:
all_items[date] = [line,]
Then, you can create a new list using the sorted date for keys.
If all of the elements with the same date are consecutive, you can use itertools.groupby:
list(map(list, groupby(data, lambda value: ...)))

I have a list in values of a dictionary and I want the first index of the list. How to iterate through it?

My dict looks like this.
{'a':0,'is_target':False,'properties':[{'id':19,'title':{'x':0,'y':1,'z':2}},{'id':20,'title':{'x':0,'y':1,'z':2}}]}
I want to group all the id's.
So Far I have tried using maps,also tried creating a new dict from the items and iterating over it. but I couldn't group.
I think you want to find all the 'id's from this dict. You could do -
final_list = []
for i in d['properties']:
final_list.append(i['id'])
final_list has all the 'id's.
parthagar answer equal to:
d = {'a':0,
'is_target':False,
'properties':[{'id':19,'title':{'x':0,'y':1,'z':2}},
{'id':20,'title':{'x':0,'y':1,'z':2}}]}
final_list = [i["id"] for i in d['properties']]
You can get to these via list comprehension
ids = [i['id'] for i in d['properties']]
[19, 20]

Create dictionary from splitted strings from list of strings

I feel that this is very simple and I'm close to solution, but I got stacked, and can't find suggestion in the Internet.
I have list that looks like:
my_list = ['name1#1111', 'name2#2222', 'name3#3333']
In general, each element of the list has the form: namex#some_number.
I want to make dictionary in pretty way, that has key = namex and value = some_number. I can do it by:
md = {}
for item in arguments:
md[item.split('#')[0]] = item.split('#')[1]
But I would like to do it in one line, with list comprehension or something. I tried do following, and I think I'm not far from what I want.
md2 = dict( (k,v) for k,v in item.split('#') for item in arguments )
However, I'm getting error: ValueError: too many values to unpack. No idea how to get out of this.
You actually don't need the extra step of creating the tuple
>>> my_list = ['name1#1111', 'name2#2222', 'name3#3333']
>>> dict(i.split('#') for i in my_list)
{'name3': '3333', 'name1': '1111', 'name2': '2222'}

CSV module sorted output unexpected

In the code below (for printing salaries in descending order, ordered by profession),
reader = csv.DictReader(open('salaries.csv','rb'))
rows = sorted(reader)
a={}
for i in xrange(len(rows)):
if rows[i].values()[2]=='Plumbers':
a[rows[i].values()[1]]=rows[i].values()[0]
t = [i for i in sorted(a, key=lambda key:a[key], reverse=True)]
p=a.values()
p.sort()
p.reverse()
for i in xrange(len(a)):
print t[i]+","+p[i]
when i put 'Plumbers' in the conditional statement, the output among the salaries of plumbers comes out to be :
Tokyo,400
Delhi,300
London,100
and when i put 'Lawyers' in the same 'if' condition, output is:
Tokyo,800
London,700
Delhi,400
content of CSV go like:
City,Job,Salary
Delhi,Lawyers,400
Delhi,Plumbers,300
London,Lawyers,700
London,Plumbers,100
Tokyo,Lawyers,800
Tokyo,Plumbers,400
and when i remove --> if rows[i].values()[2]=='Plumbers': <-- from the program,
then it was supposed to print all the outputs but it prints only these 3:
Tokyo,400
Delhi,300
London,100
Though output should look something like:
Tokyo,800
London,700
Delhi,400
Tokyo,400
Delhi,300
London,100
Where is the problem exactly?
First of all, your code works as described... outputs in descending salary order. So works as designed?
In passing, your sorting code seems overly complex. You don't need to split the location/salary pairs into two lists and sort them independently. For example:
# Plumbers
>>> a
{'Delhi': '300', 'London': '100', 'Tokyo': '400'}
>>> [item for item in reversed(sorted(a.iteritems(),key=operator.itemgetter(1)))]
[('Tokyo', '400'), ('Delhi', '300'), ('London', '100')]
# Lawyers
>>> a
{'Delhi': '400', 'London': '700', 'Tokyo': '800'}
>>> [item for item in reversed(sorted(a.iteritems(),key=operator.itemgetter(1)))]
[('Tokyo', '800'), ('London', '700'), ('Delhi', '400')]
And to answer your last question, when you remove the 'if' statement: you are storing location vs. salary in a dictionary and a dictionary can't have duplicate keys. It will contain the last update for each location, which based on your input csv, is the salary for Plumbers.
First of all, reset all indices to index - 1 as currently rows[i].values()[2] cannot equal Plumbers unless the DictReader is a 1-based index system.
Secondly, what is unique about the Tokyo in the first row of you desired output and the Tokyo of the third row? When you create a dict, using the same value as a key will result in overwriting whatever was previously associated with that key. You need some kind of unique identifier, such as Location.Profession for the key. You could simply do the following to get a key that will preserve all of your information:
key = "".join([rows[i].values()[0], rows[i].values()[1]], sep=",")

Finding values in a list of key/value pairs

I have 2 lists
old_name_list = [a-1234, a-1235, a-1236]
new_name_list = [(a-1235, a-5321), (a-1236, a-6321), (a-1234, a-4321), ... ]
I want to search recursively if the elements in old_name_list exist in new_name_list and returns the associated value with it, for eg. the first element in old_name_list returns a-4321, second element returns a-5321, and so on until old_name_list finishes.
I have tried the following and it doesn't work
for old_name, new_name in zip(old_name_list, new_name_list):
if old_name in new_name[0]:
print new_name[1]
Is the method I am doing wrong or I have to make some minor changes to it? Thank you in advance.
Build a dict() based on your second list, and lookup in that.
old_name_list = ["a-1234", "a-1235", "a-1236"]
new_name_list = [("a-1235", "a-5321"), ("a-1236", "a-6321"), ("a-1234", "a-4321") ]
d = dict(new_name_list)
for n in old_name_list:
print d[n]
You do need to put quotes around strings like "a-1234".
Using a dictionary may be the best way to do this.
old_name_list = ['a-1234', 'a-1235', 'a-1236']
new_name_list = [('a-1235', 'a-5321'), ('a-1236', 'a-6321'), ('a-1234, a-4321')]
mapping = dict(new_name_list)
values = [mapping[item] if item in mapping for item in old_name_list]
print values
Use this:
found_items = [item[1] for item in new_name_list if item[0] in old_name_list]

Categories

Resources