I have a list of strings that contains elements of the type
List=['name1,vol', 'name1,price','name2, vol', 'name2,price'.... ]
I would like to extract a list only of "names" which are the parts that actually change as the second components in each element have a fix pattern (here:vol, price). Notice that the "names" can obviously have different length. To sum up, I'd like to extract something like:
List_names=['name1', 'name2' ]
How can I do that?
What if I have something of the type:
List_tricky=[('name1', 'vol'), ('name1', 'price'),('name2', 'vol'), ('name2', 'price').... ]
Something like this?
List=['name1,vol', 'name1,price','name2, vol', 'name2,price']
names = []
for string in List:
name = string.split(',')[0]
names.append(name)
print(names)
For your 'tricky' case, you can try:
# initialize variables:
names = []
# iterate over each point (tuple):
for point in List:
# get name:
name = point[0]
# append to list:
names.append(name)
print(names)
You could turn it into a dict then back into a list using str.split. (No loop required as it does it efficiently for you) Use functools.partial to apply the split to each string instead of a lambda:
from functools import partial
list(dict(map(partial(str.split, sep=','), List)))
This works for either input but way more simple for the list of tuples:
>>> l = ['name1,vol', 'name1,price','name2, vol', 'name2,price'.... ]
>>> list(dict(map(partial(str.split, sep=','), List)))
['name1', 'name2']
>>> l = [('name1', 'vol'), ('name1', 'price'),('name2', 'vol'), ('name2', 'price').... ]
>>> list(dict(l))
['name1', 'name2']
Similar logic to #Daniel Sokol's answer , you can use a one liner :
list2 = [x.split(',')[0] for x in List]
To add on top of #Alireza Tajadod's already wonderful answer, you might want to apply conversion to a set, then back to a list to remove any possible duplication items, as suggested by #Cryptoharf84 in the comments.
names_list = list(set([entry.split(',')[0] for entry in List]))
The same logic with list comprehension can be applied to the trickier case.
names_list_2 = list(set([entry[0] for entry in List_tricky]))
To make list comprehension more explicit, you can also do the following:
names_list_3 = list(set([name for name, _ in List_tricky]))
The _ indicates that we are discarding the second value of the unpacked tuple.
Sets are useful because converting a list with duplicate elements into a set effectively removes any duplications.
As a tip, look for naming conventions in python. But never name variables starting with upper case, nor with existing class names.
I will try something like:
list_names = [s.split(',')[0].strip() for s in List]
list_unique_names(set(list_names))
split returns a list of "chunks" of the original string, and strip to remove whitespaces on beginning/end of the resulting string.
I will change your data structure to dict instead of list
d={'name1': ('vol', 'price'),'name2': ('vol', 'price'), .... }
In order to get just the names:
d.keys()
You can also use a .map() function:
# Case 1: List
all_names = map(lambda x :a.split(',')[0], List)
# Case 2: List_tricky
all_names = [i[0] for i in List_tricky]
# After the code is the same
unique_names = set(all_names)
List_names = list(unique_names)
print(List_names)
Related
Hey (Sorry bad english) so am going to try and make my question more clear. if i have a function let's say create_username_dict(name_list, username_list). which takes in two list's 1 being the name_list with names of people than the other list being usernames that is made out of the names of people. what i want to do is take does two list than convert them to a dictonary and set them together.
like this:
>>> name_list = ["Ola Nordmann", "Kari Olsen", "Roger Jensen"]
>>> username_list = ["alejon", "carli", "hanri"]
>>> create_username_dict(name_list, username_list)
{
"Albert Jones": "alejon",
"Carlos Lion": "carli",
"Hanna Richardo": "hanri"
}
i have tried look around on how to connect two different list in too one dictonary, but can't seem to find the right solution
If both lists are in matching order, i.e. the i-th element of one list corresponds to the i-th element of the other, then you can use this
D = dict(zip(name_list, username_list))
Use zip to pair the list.
d = {key: value for key,value in zip(name_list, username_list)}
print(d)
Output:
{'Ola Nordmann': 'alejon', 'Kari Olsen': 'carli', 'Roger Jensen': 'hanri'}
Considering both the list are same length and one to one mapping
name_list = ["Ola Nordmann", "Kari Olsen", "Roger Jensen"]
username_list = ["alejon", "carli", "hanri"]
result_stackoverflow = dict()
for index, name in enumerate(name_list):
result_stackoverflow[name] = username_list[index]
print(result_stackoverflow)
>>> {'Ola Nordmann': 'alejon', 'Kari Olsen': 'carli', 'Roger Jensen': 'hanri'}
Answer by #alex does the same but maybe too encapsulated for a beginner. So this is the verbose version.
I have a dictionary and two lists and would like to output another dictionary that contains the individual list as the title and sum of the list contents as the values however, I have no clue as to how I could do this.
results = {'Apple':'14.0', 'Banana':'12.0', 'Orange':'2.0', 'Pineapple':'9.0'}
ListA = ['Apple','Pineapple']
ListB = ['Banana','Orange']
Output:
dicttotal = {'ListA':'23.0', 'ListB':'14.0'}
Edit: I have decided to use pandas to work with the above data as I find that the simplicity of pandas is more suited for my level of understanding. Thanks for the help everyone!
in python you can use list comprehensions to make this easy to read:
items_for_a = [float(v) for i, v in results.items() if i in ListA]
total_a = sum(items_for_a)
the dicttotal you want to print is strange, though. I don't think you want to print variable names as dictionary keys.
in python2 you should use .iteritems() instead of .items()
You can use fllowing code get ListA's sum. The same way for ListB. Just try it yourself
dicttotal = {}
ListASum = 0.0
ListBSum = 0.0
for item in ListA:
if item in results:
ListASum += float(results[item])
dicttotal['ListA'] = ListASum
Reduce and dictionary comprehension to create dictionary with an initial value, followed by updating a single value. Had key names not been variable names maybe could have done dict comprehension for both.
from functools import reduce
d_total = {'ListA': str(reduce(lambda x, y: float(results[x]) + float(results[y]), lista))}
d_total['ListB'] = str(reduce(lambda x, y: float(results[x]) + float(results[y]), listb))
{'ListA': '23.0', 'ListB': '14.0'}
Note: PEP-8 snake_case for naming
One-liner, using the (ugly) eval() function, but as Eduard said, it's better not to use variable names as keys :
{list_name: str(sum([float(results[item]) for item in eval(list_name)])) for list_name in ['ListA', 'ListB']}
I'm maintaining message_id and message_writer_id together in a python list like so:
composite_items = ['1:2', '2:2', '3:2', '4:1', '5:19', '20:2', '45:1', ...]
Where each element is message_id:message_poster_id.
From the above list, I want to extract the set of all message_writer_ids. I.e. I want to extract a set containing all unique numbers after : so that I end up with:
item_set = ['2', '1', '19']
What's the most efficient way to do that in python?
Currently, I'm thinking I'll do something like:
new_list = []
for item in composite_items:
element = item.split(":")[1]
new_list.append(element)
new_set = set(new_list)
Was wondering if there's a faster way to achieve this.
You may use set comprehension like so:
new_set = {item.partition(":")[2] for item in composite_items}
Set comprehension is fast, and unlike str.split(), str.partition() splits only once and stops looking for more colons. Quite the same as with str.split(maxsplit=1).
composite_items = ['1:2', '2:2', '3:2', '4:1', '5:19', '20:2', '45:1', ...]
posters = dict()
for element in composite_items:
poster_id = element.split(":")[1]
posters[poster_id] = posters.get(poster_id, 0) + 1
You can use dictionaries and also count how many messages sent by message_poster_id. posters.get(poster_id,0) + 1 checks that a poster exists or not. If exists it gets its value (number of messages) and increment it by 1.
If doesn't exist its add the poster_id to dictionary and sets it to 0.
I have a dictionary called muncounty- the keys are municipality, county. separted by a comma and the value is a zip code
muncounty['mun'+','+'county'] = 12345
My goal is to split the keys at the comma separating the mun and county and only extract the mun.
I have tried
muncounty.keys().split(',')
i know this does not work because you cannot use the split function on a list
You need some kind of looping, e.g. a list comprehension:
[key.split(',') for key in muncounty.keys()]
You're question and example code isn't very clear, but I think what you want is this:
for key in muncounty.keys():
mun, county = key.split(',')
Your current code is trying to perform split on a list, which you quite rightly point out can't be done. What the code above does is go through each key, and performs the split on it individually.
You could use map and a lambda function.
di = {'a.b':1}
map(lambda k: k.split('.'), di.keys())
[x.split(',')[0] for x in muncounty.keys()]
But I would recommend to store your key as tuple (municipality, county).
Well, verbose mode for that:
muncounty = {}
muncounty['mun'+','+'county'] = 12345
muncounty['mun2'+','+'county2'] = 54321
l = []
for i in muncounty:
l.append(i)
muns = []
for k in l:
muns.append(k.split(',')[0])
But dude... this is a really bad way to store mun/countries ;-)
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]