determine if a list contains other lists - python

if I have a list, is there any way to check if it contains any other lists?
what i mean to say is, I want to know if a list has this strcuture: [] as opposed to this structure [[]]
so, compare [1,2,3,4] to [1,[2,3],4]
this is complicated by the fact that i have a list of strings.
well, phihag's solution seems to be working so far, but what I'm doing is this:
uniqueCrossTabs = list(itertools.chain.from_iterable(uniqueCrossTabs))
in order to flatten a list if it has other lists in it.
But since my list contains strings, if this is done on an already flattened list, I get a list of each character of each string that was in the original list.
This is not the behavior i was looking for. so, checking to see if the list needs to be flattened before flattening is neccessary.

any(isinstance(el, list) for el in input_list)

You can take phihag's answer even further if you actually want a list of all the lists inside the list:
output_list = filter( lambda x: isinstance(x,list), input_list)

lst1 in lst2
Yields True iff lst1 is in lst2.

Related

Check if a string is present in multiple lists (Python)

What is the most efficient way to check whether a set string is present in all of three given lists, and if so, set itemInAllLists to True?
Below is the general idea of what I'm trying to achieve.
item = 'test-element'
list_a = ['a','random','test-element']
list_b = ['light','apple','table']
list_c = ['car','field','test-element','chair']
itemInAllLists = False
if item in [list_a] and item in [list_b] and item in [list_c]:
itemInAllLists = True
Check if string present in multiple lists (Python)
Have a look at the all built-in for Python. It will return True if all elements of an iterable is true.
If you put all your lists in a combined list, you can do list comprehension to check each list.
all(item in all_lists for all_lists in [list_a, list_b, list_c])
As deceze mentions, you don't have to do it this way. What you are doing works as well and might be easier to read. Using all or any might be better suited for more lists or when you create them dynamically.
For your code to work, you just have to remove the brackets so the syntax is correct:
if item in list_a and item in list_b and item in list_c:
pass

Python, encode strings within a list of lists

Am using Python 2.7.
I have a list of lists like:
testList2 = [[u'462', u'San Germ\xe1n, PR'],[u'461', u'40341']]
I want to encode the strings in the list of lists like:
encodedList = [['462', 'San Germ\xc3\xa1n, PR'],['461', '40341']]
Tried to write a function to do this (did not work):
def testEncode(a):
for list in a:
return [x.encode('utf-8') for x in list]
I think that for the function to work, it needs to append each encoded list to the prior encoded list to generate an encoded list of lists. Not sure how to do this. If someone could explain how the function could be edited to do this, that would be awesome.
I tried the following which did not work either
def testEncode(a):
b = []
for list in a:
b.append([x.encode('utf-8') for x in list])
return b
Having realized that your first code is not actually a typographical error but a logical mistake, let me summarize my comments here. There are two problems (both related) in your approaches:
Problem with the first code: You are currently returning only the first sublist because you put the return in your for loop. Your input list contains sublists so you need to loop over them in a nested manner. One way is to do it as you are doing in your second approach. Another way is to use list comprehensions. Following is the list comprehension way where i will iterate through the sublists and x will iterate through the elements of your sublist i.
def testEncode(a):
return [[x.encode('utf-8') for x in i] for i in a]
Problem with the second code: In this attempt of yours, you have basically solved the problem of ignoring the sublists but you forgot to put your return statement outside the for loop. So before your nested for loop iterate through all the sublists, you prematurely return the result. Therefore, you only see the first sublist modified.
def testEncode(a):
b = []
for list in a:
b.append([x.encode('utf-8') for x in list])
return b # <-- Moved outside the for loop now

Put average of nested list values into new list

I have the following list:
x = [(27.3703703703704, 2.5679012345679, 5.67901234567901,
6.97530864197531, 1.90123456790123, 0.740740740740741,
0.440136054421769, 0.867718446601942),
(25.2608695652174, 1.73913043478261, 6.07246376811594,
7.3768115942029, 1.57971014492754, 0.710144927536232,
0.4875, 0.710227272727273)]
I'm looking for a way to get the average of each of the lists nested within the main list, and create a new list of the averages. So in the case of the above list, the output would be something like:
[[26.315],[2.145],[5.87],etc...]
I would like to apply this formula regardless of the amount of lists nested within the main list.
I assume your list of tuples of one-element lists is looking for the sum of each unpacked element inside the tuple, and a list of those options. If that's not what you're looking for, this won't work.
result = [sum([sublst[0] for sublst in tup])/len(tup) for tup in x]
EDIT to match changed question
result = [sum(tup)/len(tup) for tup in x]
EDIT to match your even-further changed question
result = [[sum(tup)/len(tup)] for tup in x]
An easy way to acheive this is:
means = [] # Defines a new empty list
for sublist in x: # iterates over the tuples in your list
means.append([sum(sublist)/len(sublist)]) # Put the mean of the sublist in the means list
This will work no matter how many sublists are in your list.
I would advise you read a bit on list comprehensions:
https://docs.python.org/2/tutorial/datastructures.html
It looks like you're looking for the zip function:
[sum(l)/len(l) for l in zip(*x)]
zip combines a collection of tuples or lists pairwise, which looks like what you want for your averages. then you just use sum()/len() to compute the average of each pair.
*x notation means pass the list as though it were individual arguments, i.e. as if you called: zip(x[0], x[1], ..., x[len(x)-1])
r = [[sum(i)/len(i)] for i in x]

Delete all occurrences of specific values from list of lists python

As far as I can see this question (surprisingly?) has not been asked before - unless I am failing to spot an equivalent question due to lack of experience. (Similar questions have
been asked about 1D lists)
I have a list_A that has int values in it.
I want to delete all occurrences of all the values specified in List_A from my list_of_lists. As a novice coder I can hack something together here myself using list comprehensions and for loops, but given what I have read about inefficiencies of deleting elements from within lists, I am looking for advice from more experienced users about the fastest way to go about this.
list_of_lists= [
[1,2,3,4,5,6,8,9],
[0,2,4,5,6,7],
[0,1,6],
[0,4,9],
[0,1,3,5],
[0,1,4],
[0,1,2],
[1,8],
[0,7],
[0,3]
]
Further info
I am not looking to eliminate duplicates (there is already a question on here about that). I am looking to eliminate all occurrences of selected values.
list_A may typically have 200 values in it
list_of_lists will have a similar (long tailed) distribution to that shown above but in the order of up to 10,000 rows by 10,000 columns
Output can be a modified version of original list_of_lists or completely new list - whichever is quicker
Last but not least (thanks to RemcoGerlich for drawing attention to this) - I need to eliminate empty sublists from with the list of lists
Many thanks
Using list comprehension should work as:
new_list = [[i for i in l if i not in list_A] for l in list_of_list]
After that, if you want to remove empty lists, you can make:
for i in new_list:
if not i:
new_list.remove(i)
of, as #ferhatelmas pointed in comments:
new_list = [i for i in new_list if i]
To avoid duplicates in list_A you can convert it to a set before with list_A = set(list_A)
I'd write a function that just takes one list (or iterable) and a set, and returns a new list with the values from the set removed:
def list_without_values(L, values):
return [l for l in L if l not in values]
Then I'd turn list_A into a set for fast checking, and loop over the original list:
set_A = set(list_A)
list_of_lists = [list_without_values(L, set_A) for L in list_of_lists]
Should be fast enough and readibility is what matters most.

append/extend list in loop

I would like to extend a list while looping over it:
for idx in xrange(len(a_list)):
item = a_list[idx]
a_list.extend(fun(item))
(fun is a function that returns a list.)
Question:
Is this already the best way to do it, or is something nicer and more compact possible?
Remarks:
from matplotlib.cbook import flatten
a_list.extend(flatten(fun(item) for item in a_list))
should work but I do not want my code to depend on matplotlib.
for item in a_list:
a_list.extend(fun(item))
would be nice enough for my taste but seems to cause an infinite loop.
Context:
I have have a large number of nodes (in a dict) and some of them are special because they are on the boundary.
'a_list' contains the keys of these special/boundary nodes. Sometimes nodes are added and then every new node that is on the boundary needs to be added to 'a_list'. The new boundary nodes can be determined by the old boundary nodes (expresses here by 'fun') and every boundary node can add several new nodes.
Have you tried list comprehensions? This would work by creating a separate list in memory, then assigning it to your original list once the comprehension is complete. Basically its the same as your second example, but instead of importing a flattening function, it flattens it through stacked list comprehensions. [edit Matthias: changed + to +=]
a_list += [x for lst in [fun(item) for item in a_list] for x in lst]
EDIT: To explain what going on.
So the first thing that will happen is this part in the middle of the above code:
[fun(item) for item in a_list]
This will apply fun to every item in a_list and add it to a new list. Problem is, because fun(item) returns a list, now we have a list of lists. So we run a second (stacked) list comprehension to loop through all the lists in our new list that we just created in the original comprehension:
for lst in [fun(item) for item in a_list]
This will allow us to loop through all the lists in order. So then:
[x for lst in [fun(item) for item in a_list] for x in lst]
This means take every x (that is, every item) in every lst (all the lists we created in our original comprehension) and add it to a new list.
Hope this is clearer. If not, I'm always willing to elaborate further.
Using itertools, it can be written as:
import itertools
a_list += itertools.chain(* itertools.imap(fun, a_list))
or, if you're aiming for code golf:
a_list += sum(map(fun, a_list), [])
Alternatively, just write it out:
new_elements = map(fun, a_list) # itertools.imap in Python 2.x
for ne in new_elements:
a_list.extend(ne)
As you want to extend the list, but loop only over the original list, you can loop over a copy instead of the original:
for item in a_list[:]:
a_list.extend(fun(item))
Using generator
original_list = [1, 2]
original_list.extend((x for x in original_list[:]))
# [1, 2, 1, 2]

Categories

Resources