How to add dictionaries inside of a list - python

I want to connect separated messages of a chat, so I created a list for all the dictionaries
messages = ["Hello", "How you doing","fine","how can I help you", "how to do this?", "like this", "thanks","man","no problem"]
Person1= [True,True,False,False,True,False,True,True,False]
data =[]
chat_messages = messages
people = Person1
k = 0
for i in range(len(messages)):
if people[i] == people[i+1]:
chat_messages[i+1] = chat_messages[i] +" " +chat_messages[i+1]
chatData = {'text': chat_messages[i+1], 'person1': people[i]}
data[k] = chatData
else:
k +=1
chatData = {'text': chat_messages[i+1], 'person1': people[i+1]}
print(chatData )
data[k] = chatData
print(data)
I'm getting errors in here
File "main.py", line 20, in <module>
data[k] = chatData
IndexError: list assignment index out of range
How can I fix it please?
I want the output of data to look like this:
data = [{'text': 'Hello How you doing', 'person1': True} , {'text': 'fine how can I help you', 'person1': False}, {'text': 'how to do this?', 'person1': True}]

You cant add elements to a list in python this way. you have to use python method append().
data.append(chatData)
This method will add elements at the end of the list.
You can learn more python list methods using this link
https://www.geeksforgeeks.org/list-methods-python/

The problem is that when you add the index i + 1, it gives an error when you get to the nr 9, because your list index stops at 8. Here is my solution:
messages = ["Hello", "How you doing","fine","how can I help you", "how to do this?", "like this", "thanks","man","no problem"]
Person1= [True,True,False,False,True,False,True,True,False]
data =[]
chat_messages = messages
people = Person1
k = 0
data = []
for i, msg in enumerate(messages):
try:
if people[i] == people[i+1]:
chat_messages[i+1] = chat_messages[i] +" " +chat_messages[i+1]
data.append({'text': chat_messages[i+1], 'person1': people[i]})
except:
pass
print(data)

messages = ["Hello", "How you doing","fine","how can I help you", "how to do this?", "like this", "thanks","man","no problem"]
Person1= [True,True,False,False,True,False,True,True,False]
data =[]
chat_messages = messages
people = Person1
k = 0
for i in range(len(messages)):
if len(messages)-1 is i:
None
else:
if people[i] == people[i+1]:
chat_messages[i+1] = chat_messages[i] +" " +chat_messages[i+1]
chatData = {'text': chat_messages[i+1], 'person1': people[i]}
data.append(chatData)
else:
chatData = {'text': chat_messages[i+1], 'person1': people[i+1]}
print(chatData )
data.append(chatData)
print(data)

Related

multiple separator in a string python

text="Brand.*/Smart Planet.#/Color.*/Yellow.#/Type.*/Sandwich Maker.#/Power Source.*/Electrical."
I have this kind of string. I am facing the problem which splits it to 2 lists. Output will be approximately like this :
name = ['Brand','Color','Type','Power Source']
value = ['Smart Plane','Yellow','Sandwich Maker','Electrical']
Is there any solution for this.
name = []
value = []
text = text.split('.#/')
for i in text:
i = i.split('.*/')
name.append(i[0])
value.append(i[1])
This is one approach using re.split and list slicing.
Ex:
import re
text="Brand.*/Smart Planet.#/Color.*/Yellow.#/Type.*/Sandwich Maker.#/Power Source.*/Electrical."
data = [i for i in re.split("[^A-Za-z\s]+", text) if i]
name = data[::2]
value = data[1::2]
print(name)
print(value)
Output:
['Brand', 'Color', 'Type', 'Power Source']
['Smart Planet', 'Yellow', 'Sandwich Maker', 'Electrical']
You can use regex to split the text, and populate the lists in a loop.
Using regex you protect your code from invalid input.
import re
name, value = [], []
for ele in re.split(r'\.#\/', text):
k, v = ele.split('.*/')
name.append(k)
value.append(v)
>>> print(name, val)
['Brand', 'Color', 'Type', 'Power Source'] ['Smart Planet', 'Yellow', 'Sandwich Maker', 'Electrical.']
text="Brand.*/Smart Planet.#/Color.*/Yellow.#/Type.*/Sandwich Maker.#/Power Source.*/Electrical."
name=[]
value=[]
word=''
for i in range(len(text)):
temp=i
if text[i]!='.' and text[i]!='/' and text[i]!='*' and text[i]!='#':
word=word+''.join(text[i])
elif temp+1<len(text) and temp+2<=len(text):
if text[i]=='.' and text[temp+1]=='*' and text[temp+2]=='/':
name.append(word)
word=''
elif text[i]=='.' and text[temp+1]=='#' and text[temp+2]=='/':
value.append(word)
word=''
else:
value.append(word)
print(name)
print(value)
this will be work...

Categorizing sentence using dictionary

I am using below function for getting categorizing sentence in themes
def theme(x):
output =[]
category = ()
for i in x:
if 'AC' in i:
category = 'AC problem'
elif 'insects' in i:
category = 'Cleanliness'
elif 'clean' in i:
category = 'Cleanliness'
elif 'food' in i:
category = 'Food Problem'
elif 'delay' in i:
category = 'Train Delayed'
else:
category = 'None'
output.append(category)
return output
I don't want to use repeated if statements for every word in a category. Instead I want the i give a list/dictionary e.g. Cleanliness = ['Clean', 'Cleaned', 'spoilt', 'dirty'] for getting category 'Cleanliness' against the sentence if it has any of the words in list. How can i do that
You can use a dict of sets to structure your words with categories, and then generate a word-to-category lookup dict based on the said structure:
categories = {
'Cleanliness': {'insects', 'clean'},
'AC Problem': {'AC'},
'Food Problem': {'food'},
'Train Delayed': {'delay'}
}
lookup = {word: category for category, words in categories.items() for word in words}
def theme(x):
return {lookup.get(word, 'None') for word in x}
so that theme(['AC', 'clean', 'insects']) would return a set of corresponding categories:
{'Cleanliness', 'AC Problem'}
This should do what you're asking. I set all the keys to lowercase and converted i to lowercase when checking if you get a match, but with different capitalization, it still counts.
def theme(x):
output =[]
category = ()
myDict = {"ac":"AC problem", "insects":"Cleanliness", "clean":"Cleanliness", "food":"Food Problem", "delay":"Train Delayed"} #I reccomend coming up with a more suitable name for your dictionary in your actual program
for i in x:
if i.lower() in myDict: #Checks to see if i is in the dictionary before trying to print the result; prevents possible Key Errors
category = (myDict[i.lower()]) #If it is in the dictionary it category will be set to the result of the key
output.append(category)
else:
output.append("None") #If i isn't in the dictionary output will append None instead
return output
Here's some examples:
>>>print(theme(['Clean', 'Cleaned', 'spoilt', 'dirty']))
['Cleanliness', 'None', 'None', 'None']
>>>print(theme(['Delay', 'Ham', 'Cheese', 'Insects']))
['Train Delayed', 'None', 'None', 'Cleanliness']
I have worked out a another way:
def theme(x):
output = []
for i in x:
if set(cleanliness).intersection(i.lower().split()):
category = 'clean'
elif set(ac_problem).intersection(i.lower().split()):
category = 'ac problem'
else:
category = 'none'
output.append(category)
return output
Maybe you can do it like this:
def theme(x):
output = []
name_dic = {"AC": "AC problem",
"clean": "Cleanliness",
"food": "Food Problem"
}
for e in x:
output.append(name_dic.get(e))
return output
Or more exactly like this:
def theme(x):
output = []
name_list = [
("AC", "AC problem"),
("clean", "Cleanliness"),
("insects", "Cleanliness"),
("food", "Food Problem")
]
name_dic = dict(name_list)
for e in x:
output.append(name_dic.get(e))
return output
Hope it helps.

python NoneType attribute error

I am getting "AttributeError: 'NoneType' object has no attribute 'count'" with following code. Pls help in resolving same.
def search_albums(self, query, _dir = None):
from pprint import pprint
url = self.urls['search_albums_new']
url = url.format(query = query)
response = self._get_url_contents(url)
albums = response.json()['album']
if albums:
albums_list = map(lambda x:[x['album_id'],x['title'], x['language'], x['seokey'], x['release_date'],','.join(map(lambda y:y['name'], x.get('artists',[])[:2])) ,x['trackcount']], albums)
tabledata = [['S No.', 'Album Title', 'Album Language', 'Release Date', 'Artists', 'Track Count']]
for idx, value in enumerate(albums_list):
tabledata.append([str(idx), value[1], value[2], value[4], value[5], value[6]])
table = AsciiTable(tabledata)
print table.table
idx = int(raw_input('Which album do you wish to download? Enter S No. :'))
album_details_url = self.urls['album_details']
album_details_url = album_details_url.format(album_id = albums_list[idx][0])
response = requests.get(album_details_url , headers = {'deviceType':'AndroidApp', 'appVersion':'V5'})
tracks = response.json()['tracks']
tracks_list = map(lambda x:[x['track_title'].strip(),x['track_id'],x['album_id'],x['album_title'], ','.join(map(lambda y:y['name'], x['artist'])), x['duration']], tracks)
print 'List of tracks for ', albums_list[idx][1]
tabledata = [['S No.', 'Track Title', 'Track Artist']]
for idy, value in enumerate(tracks_list):
tabledata.append([str(idy), value[0], value[4]])
tabledata.append([str(idy+1), 'Enter this to download them all.',''])
table = AsciiTable(tabledata)
print table.table
print 'Downloading tracks to %s folder'%albums_list[idx][3]
ids = raw_input('Please enter csv of S no. to download:')
while not self._check_input(ids, len(tracks_list)) or not ids:
print 'Oops!! You made some error in entering input'
ids = raw_input('Please enter csv of S no. to download:')
if not _dir:
_dir = albums_list[idx][3]
self._check_path(_dir)
ids = map(int,map(lambda x:x.strip(),ids.split(',')))
if len(ids) == 1 and ids[0] == idy + 1:
for item in tracks_list:
song_url = self._get_song_url(item[1], item[2])
self._download_track(song_url, item[0].replace(' ','-').strip(), _dir)
else:
for i in ids:
item = tracks_list[i]
song_url = self._get_song_url(item[1], item[2])
self._download_track(song_url, item[0].replace(' ','-').strip(), _dir)
else:
print 'Ooopsss!!! Sorry no such album found.'
print 'Why not try another Album? :)'
Error :
Traceback (most recent call last): File "a-dl.py", line 163, in
d.search_albums(args.album) File "a-dl.py", line 116, in search_albums
print table.table File "C:\Python27\lib\site-packages\terminaltables.py", line 337, in table
padded_table_data = self.padded_table_data File "C:\Python27\lib\site-packages\terminaltables.py", line 326, in
padded_table_data
height = max([c.count('\n') for c in row] or [0]) + 1 AttributeError: 'NoneType' object has no attribute 'count'
well few hit and trial and i got my answer.
I changed following
albums_list = map(lambda x:[x['album_id'],x['title'], x['language'], x['seokey'], x['release_date'],','.join(map(lambda y:y['name'], x.get('artists',[])[:2])) ,x['trackcount']], albums)
tabledata = [['S No.', 'Album Title', 'Album Language', 'Release Date', 'Artists', 'Track Count']]
for idx, value in enumerate(albums_list):
tabledata.append([str(idx), value[1], value[2], value[4], value[5], value[6]])
with
albums_list = map(lambda x:[x['album_id'],x['title'], x['language'], x['seokey'], x['release_date']], albums)
tabledata = [['S No.', 'Album Title', 'Album Language', 'Release Date']]
for idx, value in enumerate(albums_list):
tabledata.append([str(idx), value[1], value[2], value[4]])
and it worked fine now :)

Python. How do I make a list of small portions of a bigger list?

for word in list6:
if word = "TRUMP":
So, I have a list of every word in a debate transcript. When Trump speaks, it starts with "TRUMP". I need to take his words and put them into a seperate list. If the word in list6 is "TRUMP", then I need to put everything into a list until it says another person's name. He speaks more than once.
I just need help completing this loop.
list6 = ['TRUMP','I','am','good', 'HILLARY','I','am','good','too','TRUMP','But','How?']
person_words = {'TRUMP':[], 'HILLARY':[]}
person_names = person_words.keys()
one_person_onetime_words = []
for word in list6:
if word in person_names:
if len(one_person_onetime_words):
person_words[this_person].append(one_person_onetime_words)
one_person_onetime_words = []
this_person = word
else:
one_person_onetime_words.append(word)
person_words[this_person].append(one_person_onetime_words)
print person_words
Gives
{'HILLARY': [['I', 'am', 'good', 'too']], 'TRUMP': [['I', 'am', 'good'], ['But', 'How?']]}
So, this in a single shot gives all the different talks by all the persons.
As mentioned by you in the comments to your question, if you want to get one person's words only you can use the following:
from copy import copy
list6 = ['TRUMP','I','am','good', 'HILLARY','I','am','good','too','TRUMP','But','How?']
person_words = []
all_persons = ['TRUMP', 'HILLARY']
person_looking_for = 'TRUMP'
filter_out_persons = copy(all_persons)
filter_out_persons.remove(person_looking_for)
person_onetime_words = []
capture_words = False
for word in list6:
if word == person_looking_for:
capture_words = True
if len(person_onetime_words):
person_words.append(person_onetime_words)
person_onetime_words = []
elif word not in filter_out_persons and capture_words:
person_onetime_words.append(word)
else:
capture_words = False
person_words.append(person_onetime_words)
print "{}'s words".format(person_looking_for)
print person_words
That gives
TRUMP's words
[['I', 'am', 'good'], ['But', 'How?']]
And, the following will give a dictionary with words as keys and the value will be a dictionary again with frequency of each person for that word.
import pprint
list6 = ['TRUMP','I','am','good', 'HILLARY','I','am','good','too','TRUMP','But','How?']
person_names = ['TRUMP','HILLARY']
word_frequency = {}
for word in list6:
if word in person_names:
person = word
else:
word = word.lower()
if word in word_frequency:
if person in word_frequency[word]:
word_frequency[word][person] += 1
else:
word_frequency[word][person] = 1
else:
word_frequency[word] = {person: 1}
pprint.pprint(word_frequency)
Gives
{'am': {'HILLARY': 1, 'TRUMP': 1},
'but': {'TRUMP': 1},
'good': {'HILLARY': 1, 'TRUMP': 1},
'how?': {'TRUMP': 1},
'i': {'HILLARY': 1, 'TRUMP': 1},
'too': {'HILLARY': 1}}

Failing to append to dictionary. Python

I am experiencing a strange faulty behaviour, where a dictionary is only appended once and I can not add more key value pairs to it.
My code reads in a multi-line string and extracts substrings via split(), to be added to a dictionary. I make use of conditional statements. Strangely only the key:value pairs under the first conditional statement are added.
Therefore I can not complete the dictionary.
How can I solve this issue?
Minimal code:
#I hope the '\n' is sufficient or use '\r\n'
example = "Name: Bugs Bunny\nDOB: 01/04/1900\nAddress: 111 Jokes Drive, Hollywood Hills, CA 11111, United States"
def format(data):
dic = {}
for line in data.splitlines():
#print('Line:', line)
if ':' in line:
info = line.split(': ', 1)[1].rstrip() #does not work with files
#print('Info: ', info)
if ' Name:' in info: #middle name problems! /maiden name
dic['F_NAME'] = info.split(' ', 1)[0].rstrip()
dic['L_NAME'] = info.split(' ', 1)[1].rstrip()
elif 'DOB' in info: #overhang
dic['DD'] = info.split('/', 2)[0].rstrip()
dic['MM'] = info.split('/', 2)[1].rstrip()
dic['YY'] = info.split('/', 2)[2].rstrip()
elif 'Address' in info:
dic['STREET'] = info.split(', ', 2)[0].rstrip()
dic['CITY'] = info.split(', ', 2)[1].rstrip()
dic['ZIP'] = info.split(', ', 2)[2].rstrip()
return dic
if __name__ == '__main__':
x = format(example)
for v, k in x.iteritems():
print v, k
Your code doesn't work, at all. You split off the name before the colon and discard it, looking only at the value after the colon, stored in info. That value never contains the names you are looking for; Name, DOB and Address all are part of the line before the :.
Python lets you assign to multiple names at once; make use of this when splitting:
def format(data):
dic = {}
for line in data.splitlines():
if ':' not in line:
continue
name, _, value = line.partition(':')
name = name.strip()
if name == 'Name':
dic['F_NAME'], dic['L_NAME'] = value.split(None, 1) # strips whitespace for us
elif name == 'DOB':
dic['DD'], dic['MM'], dic['YY'] = (v.strip() for v in value.split('/', 2))
elif name == 'Address':
dic['STREET'], dic['CITY'], dic['ZIP'] = (v.strip() for v in value.split(', ', 2))
return dic
I used str.partition() here rather than limit str.split() to just one split; it is slightly faster that way.
For your sample input this produces:
>>> format(example)
{'CITY': 'Hollywood Hills', 'ZIP': 'CA 11111, United States', 'L_NAME': 'Bunny', 'F_NAME': 'Bugs', 'YY': '1900', 'MM': '04', 'STREET': '111 Jokes Drive', 'DD': '01'}
>>> from pprint import pprint
>>> pprint(format(example))
{'CITY': 'Hollywood Hills',
'DD': '01',
'F_NAME': 'Bugs',
'L_NAME': 'Bunny',
'MM': '04',
'STREET': '111 Jokes Drive',
'YY': '1900',
'ZIP': 'CA 11111, United States'}

Categories