Get inner-most elements from triple nested list Python - python

I have list
players = [[['QB1',7000,20],['RB1',4500,12],['RB2',3800,11]],
[['QB1',7000,20],['RB2',3800,11],['RB1',4500,12]]]
How do I get the first element of each inner-most lists ('QB1', 'RB1' and 'RB2' from the first "secondary," if you will, list) to check if they are the same, however disordered labels as those in another secondary list (they are in this case as both secondary lists contain 'QB1', 'RB1' and 'RB2')?
EDIT:
My desired out is [['QB1','RB1','RB2'],['QB1','RB2','RB1']]. I want to have some way of identifying that these are, for my purpose, the same list.

You can do this:
output = [[i[0] for i in a] for a in players]
The output will be like this:
[['QB1', 'RB1', 'RB2'], ['QB1', 'RB2', 'RB1']]

you can use recursive search for that and get first element of each list or whole list
players = [[['QB1',7000,20],['RB1',4500,12],['RB2',3800,11]],[['QB1',7000,20],['RB2',3800,11],['RB1',4500,12]]]
def retrive_first(lst):
for item in lst:
if type(item) == list:
retrive_first(item)
else:
print "returning ---> ", lst[0]
return lst[0]
print retrive_first(players)

You could also try this:
from operator import itemgetter
[list(map(itemgetter(0), player)) for player in players]

do:
print(list(zip(players))[0])
Or:
print([i[0] for i in players])

Related

Find Numbers in a List Consisting of Strings and Convert them to Floats

I'm trying to do an exercise where I have a list:
list_1 = ['chocolate;1.20', 'book;5.50', 'hat;3.25']
And I have to make a second list out of it that looks like this:
list_2 = [['chocolate', 1.20], ['book', 5.50], ['hat', 3.25]]
In the second list the numbers have to be floats and without the ' '
So far I've come up with this code:
for item in list_1:
list_2.append(item.split(';'))
The output looks about right:
[['chocolate', '1.20'], ['book', '5.50'], ['hat', '3.25']]
But how do I convert those numbers into floats and remove the double quotes?
I tried:
for item in list_2:
if(item.isdigit()):
item = float(item)
Getting:
AttributeError: 'list' object has no attribute 'isdigit'
list_1 = ['chocolate;1.20', 'book;5.50', 'hat;3.25']
list_2 = [x.split(';') for x in list_1]
list_3 = [[x[0], float(x[1])] for x in list_2]
item is a list like ['chocolate', '1.20']. You should be calling isdigit() on item[1], not item. But isdigit() isn't true when the string contains ., so that won't work anyway.
Put the split string in a variable, then call float() on the second element.
for item in list_1:
words = item.split(';')
words[1] = float(words[1])
list_2.append(words)
I don't know if this helpful for you.
But,I think using function is better than just using simple for loop
Just try it.
def list_map(string_val,float_val):
return [string_val,float_val]
def string_spliter(list_1):
string_form=[]
float_form=[]
for string in list_1:
str_val,float_val=string.split(";")
string_form.append(str_val)
float_form.append(float_val)
return string_form,float_form
list_1 = ['chocolate;1.20', 'book;5.50', 'hat;3.25']
string_form,float_form=string_spliter(list_1)
float_form=list(map(float,float_form))
output=list(map(list_map,string_form,float_form))
print(output)
Your way of creating list_2 is fine. To then make your new list, you can use final_list = [[i[0], float(i[1])] for i in list_2]
You could also do it in the for loop like this:
for item in list_1:
split_item = item.split(';')
list_2.append([split_item[0], float(split_item[1])])
This can be achieved in two lines of code using list comprehensions.
list_1 = ['chocolate;1.20', 'book;5.50', 'hat;3.25']
list_2 = [[a, float(b)] for x in list_1 for a, b in [x.split(';', 1)]]
The second "dimension" to the list comprehension generates a list with a single sublist. This lets us essentially save the result of splitting each item and then bind those two items to a and b to make using them cleaner that having to specify indexes.
Note: by calling split with a second argument of 1 we ensure the string is only split at most once.
You can use a function map to convert each value.
def modify_element(el):
name, value = el.split(';')
return [name, float(value)]
list_1 = ['chocolate;1.20', 'book;5.50', 'hat;3.25']
result = list(map(modify_element, list_1))
For a problem like this you can initialize two variables for the result of calling the split function and then append a list of both values and call the builtin float function on the second value.
array = []
for i in a_list:
string, number = i.split(";")
array.append([string, float(number)])
print(array)

How can I delete a specific cell using .remove() in python

Say I have a list that looks like this
f = [['person','place','item'],['george','home','phone']]
how would I search through that list and delete a specific cell using f.remove()
I have tried:
f.remove('item')
which should remove 'item' but instead it returns the error
Exception has occurred: ValueError
list.remove(x): x not in list
you have list of lists, if you want to remove item from 1st list, you should do the following way:
f[0].remove('item')
.remove() is inplace operation and doesn't return any value. i.e it will change the list itself, so after above operation your list will be:
print(f)
# output [['person', 'place'], ['george', 'home', 'phone']]
for second list:
f[1].remove('home')
You can use list comprehension to do this. You need to put the if statement inside the inner loop.
f = [['person','place','item'],['george','home','phone']]
f = [[a for a in x if a != 'item'] for x in f]
The output of this will be:
[['person', 'place'], ['george', 'home', 'phone']]
This is equivalent to:
f = [['person','place','item'],['george','home','phone']]
new_f = []
for x in f:
temp_list = []
for a in x:
if a != 'item':
temp_list.append(a)
new_f.append(temp_list)
print (new_f)
The output of both will be the same.
Have you tried this?
f[0].remove('item')
You can do it easily using list comprehension
f=[x.remove('item') if 'item' in x else x for x in f]
In your example f is a two-dimensional list, so all the items in f are also lists, and item is not one of them. Depending on your use case, I can see multiple ways of interpreting "remove":
If you want your resulting list to be [['person','place'],['george','home','phone']], you can use
f[0].remove('item')
If you want your resulting list to be [['person','place'],['george','home']] (i.e. removing the whole "column" from the 2D list), then you should first find the index you want to remove, and then use del based on the index:
index = f[0].index('item')
for row in f:
del row[index]

Common items in list of lists

I have a list of lists, and I want to make a function that checks if each of the lists inside have exactly one item in common with all the other lists, if so return True.
Couldn't make it work, is there a simple way to do it without using modules?
I've tried something like this:
list_of_lists = [['d','b','s'],['e','b','f'],['s','f','l'],['b','l','t']]
new_list = []
for i in list_of_lists:
for item in i:
new_list.append(item)
if len(set(new_list)) == len(new_list)-len(list_of_lists):
return True
if you want to intersect all the items in the sublist you can convert them to a set and find intersection check if its an empty set.
list_of_lists = [['d','b','s'],['e','b','f'],['s','f','l'],['b','l','t']]
common_items = set.intersection(*[set(_) for _ in list_of_lists])
if len(common_items) == 1:
return True
return False
Using list comprehension:
def func(list_of_lists):
return sum([all([item in lst for lst in list_of_lists[1:]]) for item in list_of_lists[0]]) == 1
Works if each is guaranteed for one of each item. Also if its not, returns True only if there is one match.
use the Counter after joining a list and a compare list to determine occurrences. Ensure at least one item in the resulting list has a frequency of 2.
from collections import Counter
list_of_lists = [['d','b','s'],['e','b','f'],['s','f','l'],['b','l','t']]
for i in range(len(list_of_lists)):
for j in range(i+1,len(list_of_lists)):
result=(list_of_lists[i]+list_of_lists[j])
counts=(Counter(result))
matches={x for k,x in counts.items() if x==2}
if len(matches)==0:
print("missing a match")

How to convert a list made up of one tuple into a two item list?

I have a function that returns a one item list, like so:
list = [('array_1','array_2')]
I want to change this so that the list is instead a two item one, without the parentheses or single quotes:
list = [array_1,array_2]
What would be the best way to go about doing this?
Try this
lists = [('array_1','array_2')]
print([y for x in lists for y in x])
output
['array_1', 'array_2']
Use chain.from_iterable
from itertools import chain
list(chain.from_iterable([('array_1','array_2')]))
['array_1', 'array_2']
You can try this:
lst_tuple = [('array_1', 'array_2')]
lst = []
for i in lst_tuple[0]:
lst.append(i)
By iteratating over the list that contains the tuple and appending each item to a new list, you can get this result:
['array_1', 'array_2']
You could just typecast like this.
list = list([('array_1','array_2')][0])

Optimized code to check the element of list unique or not

python3 program that takes input a list and output if it is unique or not. The following is an example:
list_a = [1,2,3,4,5] #unique
list_b = [1,2,2,3,4] #not unique
I have wrote a python3 script for this problem:
for i in range(len(list_a)):
j = i+1
for j in range(len(list_a)):
if list_a[i] == list_a[j]:
print ("not unique")
else:
print ("unique")
Is this the only way to check it. I bet it isn't! I want some optimized code that is equivalent to above or simply that ouputs "unique" or "not unique" for a given list.
Thank you in advance.
The easiest way to do this is compare length of set of given list with length of list:
if len(l) != len(set(l)):
# not unique
You can use all() and sets, this will short-circuit as soon as a repeated item is found.
>>> def solve(lis):
... seen = set()
... return all(item not in seen and not seen.add(item) for item in lis)
...
>>> solve(range(5))
True
>>> solve([1,2,2,3,4])
False
Throw the list into a set:
set_a = set(list_a)
if len(set_a) == len(list_a):
print("unique")
else:
print("not unique")
You could use AVL Trees, add each element one by one in the tree while the inserted element is not yet in the tree.
In the case of big lists, it will be very fast in comparison of your current code.
If you want to easily find duplicate elements you can use collections.Counter:
import collections
a = [1, 2, 2, 3]
b = collections.Counter(a)
duplicates = [i for i in b if b[i] > 1]
Variable b is an object which acts a bit like a dictionary with keys being values from a and values being numbers indicating how many times this value appeared in the original list.
print(b[2])
would give 2.
Variable duplicates has all duplicate elements and you can use it like this:
if duplicates:
print("not unique")
else:
print("unique")
This is longer than generating a set, but you have much more information you can use.

Categories

Resources