Python: Adding letter plus sequential numbers as values to a dictionary key - python

I want to create a dictionary like this:
{'cat': ['anm_0', 'anm_1', 'anm_2', ... 'anm_99'],
'dog': ['anm_100', 'anm_101', 'anm_102', ... 'anm_199'],
'snake': ['anm_200', 'anm_201', 'anm_202', ... 'anm_299']}
I tried to manually define them this way:
anmdict = {}
anmdict['cat'] = "anm_" + str((list(range(0,100))))
but that outputs:
{'cat': 'anm_[0, 1, 2, 3, 4, 5, ...]'}
instead of the output with anm_0, anm_1, etc as different values.

You can use range:
_k = iter(['cat', 'dog', 'snake'])
new_d = {next(_k):[f'anm_{c}' for c in range(i, i+100)] for i in range(0, 300, 100)}
Output:
{'cat': ['anm_0', 'anm_1', 'anm_2', 'anm_3', 'anm_4', 'anm_5', 'anm_6', 'anm_7', 'anm_8', 'anm_9', 'anm_10', 'anm_11', 'anm_12', 'anm_13', 'anm_14', 'anm_15', 'anm_16', 'anm_17', 'anm_18', 'anm_19', 'anm_20', 'anm_21', 'anm_22', 'anm_23', 'anm_24', 'anm_25', 'anm_26', 'anm_27', 'anm_28', 'anm_29', 'anm_30', 'anm_31', 'anm_32', 'anm_33', 'anm_34', 'anm_35', 'anm_36', 'anm_37', 'anm_38', 'anm_39', 'anm_40', 'anm_41', 'anm_42', 'anm_43', 'anm_44', 'anm_45', 'anm_46', 'anm_47', 'anm_48', 'anm_49', 'anm_50', 'anm_51', 'anm_52', 'anm_53', 'anm_54', 'anm_55', 'anm_56', 'anm_57', 'anm_58', 'anm_59', 'anm_60', 'anm_61', 'anm_62', 'anm_63', 'anm_64', 'anm_65', 'anm_66', 'anm_67', 'anm_68', 'anm_69', 'anm_70', 'anm_71', 'anm_72', 'anm_73', 'anm_74', 'anm_75', 'anm_76', 'anm_77', 'anm_78', 'anm_79', 'anm_80', 'anm_81', 'anm_82', 'anm_83', 'anm_84', 'anm_85', 'anm_86', 'anm_87', 'anm_88', 'anm_89', 'anm_90', 'anm_91', 'anm_92', 'anm_93', 'anm_94', 'anm_95', 'anm_96', 'anm_97', 'anm_98', 'anm_99'], 'dog': ['anm_100', 'anm_101', 'anm_102', 'anm_103', 'anm_104', 'anm_105', 'anm_106', 'anm_107', 'anm_108', 'anm_109', 'anm_110', 'anm_111', 'anm_112', 'anm_113', 'anm_114', 'anm_115', 'anm_116', 'anm_117', 'anm_118', 'anm_119', 'anm_120', 'anm_121', 'anm_122', 'anm_123', 'anm_124', 'anm_125', 'anm_126', 'anm_127', 'anm_128', 'anm_129', 'anm_130', 'anm_131', 'anm_132', 'anm_133', 'anm_134', 'anm_135', 'anm_136', 'anm_137', 'anm_138', 'anm_139', 'anm_140', 'anm_141', 'anm_142', 'anm_143', 'anm_144', 'anm_145', 'anm_146', 'anm_147', 'anm_148', 'anm_149', 'anm_150', 'anm_151', 'anm_152', 'anm_153', 'anm_154', 'anm_155', 'anm_156', 'anm_157', 'anm_158', 'anm_159', 'anm_160', 'anm_161', 'anm_162', 'anm_163', 'anm_164', 'anm_165', 'anm_166', 'anm_167', 'anm_168', 'anm_169', 'anm_170', 'anm_171', 'anm_172', 'anm_173', 'anm_174', 'anm_175', 'anm_176', 'anm_177', 'anm_178', 'anm_179', 'anm_180', 'anm_181', 'anm_182', 'anm_183', 'anm_184', 'anm_185', 'anm_186', 'anm_187', 'anm_188', 'anm_189', 'anm_190', 'anm_191', 'anm_192', 'anm_193', 'anm_194', 'anm_195', 'anm_196', 'anm_197', 'anm_198', 'anm_199'], 'snake': ['anm_200', 'anm_201', 'anm_202', 'anm_203', 'anm_204', 'anm_205', 'anm_206', 'anm_207', 'anm_208', 'anm_209', 'anm_210', 'anm_211', 'anm_212', 'anm_213', 'anm_214', 'anm_215', 'anm_216', 'anm_217', 'anm_218', 'anm_219', 'anm_220', 'anm_221', 'anm_222', 'anm_223', 'anm_224', 'anm_225', 'anm_226', 'anm_227', 'anm_228', 'anm_229', 'anm_230', 'anm_231', 'anm_232', 'anm_233', 'anm_234', 'anm_235', 'anm_236', 'anm_237', 'anm_238', 'anm_239', 'anm_240', 'anm_241', 'anm_242', 'anm_243', 'anm_244', 'anm_245', 'anm_246', 'anm_247', 'anm_248', 'anm_249', 'anm_250', 'anm_251', 'anm_252', 'anm_253', 'anm_254', 'anm_255', 'anm_256', 'anm_257', 'anm_258', 'anm_259', 'anm_260', 'anm_261', 'anm_262', 'anm_263', 'anm_264', 'anm_265', 'anm_266', 'anm_267', 'anm_268', 'anm_269', 'anm_270', 'anm_271', 'anm_272', 'anm_273', 'anm_274', 'anm_275', 'anm_276', 'anm_277', 'anm_278', 'anm_279', 'anm_280', 'anm_281', 'anm_282', 'anm_283', 'anm_284', 'anm_285', 'anm_286', 'anm_287', 'anm_288', 'anm_289', 'anm_290', 'anm_291', 'anm_292', 'anm_293', 'anm_294', 'anm_295', 'anm_296', 'anm_297', 'anm_298', 'anm_299']}

Change this
anmdict['cat'] = "anm_" + str((list(range(0,100))))
To this
values = list(range(0,100))
anmdict['cat'] = ["anm_" + str(values[i]) for i in range(0,len(values))]

Related

Create a dictionary where the keys are values of dictionaries inside lists in a dictionary and the values are the number of times they appear

I have this dictionary of lists of dictionaries (I cannot change the structure for the work):
dict_countries = {'gb': [{'datetime': '1955-10-10 17:00:00', 'city': 'chester'},
{'datetime': '1974-10-10 23:00:00', 'city': 'chester'}],
'us': [{'datetime': '1955-10-10 17:00:00', 'city': 'hudson'}]
}
And the function:
def Seen_in_the_city(dict_countries:dict,)-> dict:
city_dict = {}
for each_country in dict_countries.values():
for each_sight in each_country:
citi = each_sight["city"]
if citi in city_dict.keys():
city_dict[each_sight["city"]] =+1
else:
city_dict[citi] =+1
return city_dict
I get:
{'chester': 1,'hudson': 1}
instead of
{'chester': 2,'hudson': 1}
You can try using Counter (a subclass of dict) from the collections module in the Python Standard Library:
from collections import Counter
c = Counter()
for key in dict_countries:
for d in dict_countries[key]:
c.update(v for k, v in d.items() if k == 'city')
print(c)
Output
Counter({'chester': 2, 'hudson': 1})
Try:
output = dict()
for country, cities in dict_countries.items():
for city in cities:
if city["city"] not in output:
output[city["city"]] = 0
output[city["city"]] += 1
You don't need to say +1 in order to add a positive number. Also in the if citi statement, += 1 means adding 1 to the existing value (1+1) where as =+1 is basically saying giving it a value of 1 once again.
if citi in city_dict.keys():
city_dict[each_sight["city"]] +=1
else:
city_dict[citi] = 1
You can use groupby from itertools
from itertools import groupby
print({i: len(list(j)[0]) for i,j in groupby(dict_countries.values(), key=lambda x: x[0]["city"])})
If you don't want additional imports (not that you shouldn't use Counter) here's another way:
dict_countries = {'gb': [{'datetime': '1955-10-10 17:00:00', 'city': 'chester'},
{'datetime': '1974-10-10 23:00:00', 'city': 'chester'}],
'us': [{'datetime': '1955-10-10 17:00:00', 'city': 'hudson'}]
}
def Seen_in_the_city(dict_countries:dict,)-> dict:
city_dict = {}
for each_country in dict_countries.values():
for each_sight in each_country:
citi = each_sight["city"]
city_dict[citi] = city_dict.get(citi, 0) + 1
return city_dict
print(Seen_in_the_city(dict_countries))

Collection items in Python

I have a collection of an item like below in my mongoDB database:
{u'Keywords': [[u'european', 7], [u'bill', 5], [u'uk', 5], [u'years', 4], [u'brexit', 4]], u'Link': u'http://www.bbc.com/
news/uk-politics-39042876', u'date': datetime.datetime(2017, 2, 21, 22, 47, 7, 463000), u'_id': ObjectId('58acc36b3040a218bc62c6d3')}
.....
These come from a mongo DB query
mydb = client['BBCArticles']
##mydb.adminCommand({'setParameter': True, 'textSearchEnabled': True})
my_collection = mydb['Articles']
print 'Articles containing higher occurences of the keyword is sorted as follow:'
for doc in my_collection.find({"Keywords":{"$elemMatch" : {"$elemMatch": {"$in": [keyword.lower()]}}}}):
print doc
However, I want to print documents as follow:
doc1
Kewords: european,bill, uk
Link:"http://www.bbc.com/"
doc2
....
Since your collection looks like a list of dictionaries, it should be iterable and parseable using a for-loop. If indeed you want only a portion of the url and keywords, this should work:
# c = your_collection, a list of dictionaries
from urlparse import urlparse
for n in range(len(c)):
print 'doc{n}'.format(n=n+1)
for k, v in c[n].iteritems():
if k == 'Keywords':
print k+':', ', '.join([str(kw[0]) for kw in v[0:3]])
if k == 'Link':
parsed_uri = urlparse( v )
domain = '{uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri)
print k+':', '"{0}"\n'.format(domain)
prints:
doc1
Keywords: european, bill, uk
Link: "http://www.bbc.com/"

getting the current index of a python list

I currently have the following:
jsonfiletext = jsonfile.read()
data = json.loads(jsonfiletext)
cursor.execute("SELECT CheckinID FROM checkins ORDER BY CheckinID DESC LIMIT 1")
for row in cursor.fetchall():
checkin_id = row[0]
for checkin in data:
~do stuff~
data looks like the following:
[{u'abc': u'123', u'def': u'456'}, {u'abc': u'789', u'def': u'012'}]
however, I was looking to get some form of an index or a key on the dict.
jsonfiletext = jsonfile.read()
data = json.loads(jsonfiletext)
cursor.execute("SELECT CheckinID FROM checkins ORDER BY CheckinID DESC LIMIT 1")
for row in cursor.fetchall():
checkin_id = row[0]
for checkin in data:
if checkin.index() > checkin_id:
~do stuff~
Basically, I want to avoid duplicates based on what I already have in my database.
checkin.index() would be the following:
1. {u'abc': u'123', u'def': u'456'}
2. {u'abc': u'789', u'def': u'012'}
Do you mean this?
>>> my_dict = {'age': 18, 'name': 'jhon', 'sex': 'm'}
>>> for index,item in enumerate(my_dict.items()):
print index, dict([item])
0 {'age': 18}
1 {'name': 'jhon'}
2 {'sex': 'm'}
Edit:
>>> data = [{u'abc': u'123', u'def': u'456'}, {u'abc': u'789', u'def': u'012'}]
>>> for item_with_index in enumerate(data):
print item_with_index
(0, {u'abc': u'123', u'def': u'456'})
(1, {u'abc': u'789', u'def': u'012'})

Getting the index information of a specific string in a nested list? In python 3

So I have a list with lots of nested lists in which include a students name and their test score, I was wondering how to retrieve the index (position) of the sub list that contains a specific students scores by searching with the variable 'name' that the user enters when the quiz starts. The lists sub list are created from the import of a text file, the code i used for that is:
with open('class1quizscoreboard.txt') as scoreboard:
for line in scoreboard:
importedscores.append(line.strip().split(',')
This works and the list looks like this:
[['EmilyScott ', ' 3'], ['Student Name ', ' 2'], ['Another Student ', ' 1'], ['Third Student ', ' 10']]
So I want to find the sublist by searching with the variable name, then find the position of that sublist IF the name is already in the list of scores. I would then add another test score into the list, but if it is not there just create another list.
I thought of approaching this with an IF with FOR loop, but didn't work
for sublist in importedscores:
if sublist[0] == search:
print ("Found it!"), sublist
Returned 'not found' even though I used a name I knew was definitely in the list
I am probably approaching this in the complete wrong way but the end goal is to be able to add the students new score to their existing list if they already have one
Thank you for any help
By dictionary:
Read txt file by csv module because file have well define structure.
Create dictionary from the file content where key is name and value is integer number i.e. score
Add new score for existing student.
Create new entry for new sequent.
Demo:
import csv
import pprint
p = "input34.txt"
with open(p, "rb") as fp:
root = csv.reader(fp, delimiter=',')
result = {}
for i in root:
result[i[0].strip()] = int(i[1].strip())
print "Debug1 result:"
pprint.pprint (result)
serach_key = "Test student"
add_value = 5
if serach_key in result:
result[serach_key] = result[serach_key] + add_value
else:
result[serach_key] = add_value
print "Debug2 result:"
pprint.pprint (result)
serach_key = "Another Student"
add_value = 5
if serach_key in result:
result[serach_key] = result[serach_key] + add_value
else:
result[serach_key] = add_value
print "Debug3 result:"
pprint.pprint (result)
Output:
vivek#vivek:~/Desktop/stackoverflow$ python 34.py
Debug1 result:
{'Another Student': 1,
'Emily Scott': 3,
'Student Name': 2,
'Third Student': 10}
Debug2 result:
{'Another Student': 1,
'Emily Scott': 3,
'Student Name': 2,
'Test student': 5,
'Third Student': 10}
Debug3 result:
{'Another Student': 6,
'Emily Scott': 3,
'Student Name': 2,
'Test student': 5,
'Third Student': 10}
By list:
Demo:
mport csv
import pprint
p = "input34.txt"
with open(p, "rb") as fp:
root = csv.reader(fp, delimiter=',')
result = []
for i in root:
result.append([i[0].strip(), int(i[1].strip())])
print "Debug1 result:"
pprint.pprint (result)
serach_key = "Test student"
add_value = 5
add_flag = False
for i,j in enumerate(result):
if serach_key==j[0]:
j[1] = j[1] + add_value
add_flag = True
break
if add_flag==False:
result.append([serach_key, add_value])
print "Debug2 result:"
pprint.pprint (result)
serach_key = "Another Student"
add_value = 5
add_flag = False
for i,j in enumerate(result):
if serach_key==j[0]:
j[1] = j[1] + add_value
add_flag = True
break
if add_flag==False:
result.append([serach_key, add_value])
print "Debug3 result:"
pprint.pprint (result)
Output:
vivek#vivek:~/Desktop/stackoverflow$ python 34.py
Debug1 result:
[['Emily Scott', 3],
['Student Name', 2],
['Another Student', 1],
['Third Student', 10]]
Debug2 result:
[['Emily Scott', 3],
['Student Name', 2],
['Another Student', 1],
['Third Student', 10],
['Test student', 5]]
Debug3 result:
[['Emily Scott', 3],
['Student Name', 2],
['Another Student', 6],
['Third Student', 10],
['Test student', 5]]
Use collection.defaultdict to optimize code. So no need to check key is in dictionary or not.
e.g.:
>>> import collections
>>> result = collections.defaultdict(int)
>>> result["student 1"] = 10
>>> result["student 2"] = 20
>>> print result
defaultdict(<type 'int'>, {'student 1': 10, 'student 2': 20})
>>> result["student 2"] = result["student 2"] + 2
>>> print result
defaultdict(<type 'int'>, {'student 1': 10, 'student 2': 22})
>>> result["student 3"] = result["student 3"] + 5
>>> print result
defaultdict(<type 'int'>, {'student 1': 10, 'student 2': 22, 'student 3': 5})
>>>
Try this:
def find_index(name,list):
for i, j in enumerate(list) :
if name in j :
return ('{}'.format(i))
for i, j in list:
if name == i:
ind = int(find_index(name, list))
list[ind].append(score)
Here in the find_index function the i represents the index and the j the sublist. - if name in sublist, return the index
In the for loop the i and j represent every subsection in the list. Its a bit hard to explain, but the i is the name and j the score

Merging list of dictionary in python

I have a list of dictionaries in python. Now how do i merge these dictionaries into single entity in python.
Example dictionary is
input_dictionary = [{"name":"kishore", "playing":["cricket","basket ball"]},
{"name":"kishore", "playing":["volley ball","cricket"]},
{"name":"kishore", "playing":["cricket","hockey"]},
{"name":"kishore", "playing":["volley ball"]},
{"name":"xyz","playing":["cricket"]}]
output shouled be:
[{"name":"kishore", "playing":["cricket","basket ball","volley ball","hockey"]},{"name":"xyz","playing":["cricket"]}]
Using itertools.groupby:
input_dictionary = [{"name":"kishore", "playing":["cricket","basket ball"]},
{"name":"kishore", "playing":["volley ball","cricket"]},
{"name":"kishore", "playing":["cricket","hockey"]},
{"name":"kishore", "playing":["volley ball"]},
{"name":"xyz","playing":["cricket"]}]
import itertools
import operator
by_name = operator.itemgetter('name')
result = []
for name, grp in itertools.groupby(sorted(input_dictionary, key=by_name), key=by_name):
playing = set(itertools.chain.from_iterable(x['playing'] for x in grp))
# If order of `playing` is important use `collections.OrderedDict`
# playing = collections.OrderedDict.fromkeys(itertools.chain.from_iterable(x['playing'] for x in grp))
result.append({'name': name, 'playing': list(playing)})
print(result)
output:
[{'playing': ['volley ball', 'basket ball', 'hockey', 'cricket'], 'name': 'kishore'}, {'playing': ['cricket'], 'name': 'xyz'}]
toutput = {}
for entry in input_dictionary:
if entry['name'] not in toutput: toutput[entry['name']] = []
for p in entry['playing']:
if p not in toutput[entry['name']]:
toutput[entry['name']].append(p)
output = list({'name':n, 'playing':l} for n,l in toutput.items())
Produces:
[{'name': 'kishore', 'playing': ['cricket', 'basket ball', 'volley ball', 'hockey']}, {'name': 'xyz', 'playing': ['cricket']}]
Or, using sets:
from collections import defaultdict
toutput = defaultdict(set)
for entry in input_dictionary:
toutput[entry['name']].update(entry['playing'])
output = list({'name':n, 'playing':list(l)} for n,l in toutput.items())
This is basically a slight variant of #perreal's answer (the answer before the defaultdict version was added, I mean!)
merged = {}
for d in input_dictionary:
merged.setdefault(d["name"], set()).update(d["playing"])
output = [{"name": k, "playing": list(v)} for k,v in merged.items()]
from collections import defaultdict
result = defaultdict(set)
[result[k[1]].update(v[1]) for k,v in [d.items() for d in input_dictionary]]
print [{'name':k, 'playing':v} for k,v in result.items()]

Categories