This below appends the s to the list l
s = pd.Series([1], name='foo')
l = []
l.append(s)
This only appends 1 to l
s = pd.Series([1], name='foo')
l = list(s)
How to implement the first script the best way without declaring a list and then appending?
[x] makes a list with x as an element.
list(x) makes a list produced by iterating over x. x has to be iterable, otherwise you'll get an error.
It is, in effect, [i for i in x], or
alist = []
for i in x:
alist.append(i)
Related
I have following very simple implementation in python
m = []
l = []
l.append('A')
l.append('B')
l.append('C')
m.append(l)
l.clear()
print(m) --> this gives empty list.
i tried
m = []
l = []
n = []
l.append('A')
l.append('B')
l.append('C')
n = l
m.append(n)
l.clear()
print(m) --> this gives empty list too
But when i do not clear l, print(m) give me desired list which is ['A','B','C']. Why python clears list m when i clear list l. they are 2 separate variables?
When you are passing a list to another list then it is taking its reference there
So when you cleared that list your original list's element is also cleared
Try this
m = []
l = []
l.append('A')
l.append('B')
l.append('C')
m.append(l.copy()) -> use list.copy()
l.clear()
print(m)
Both variables are reference pointing to the same object. to make a new list you need to use n = l[:]
An alternative to list.copy:
m.append(l[:])
or
m.append(list(l))
The will append to m a "freshly" created list.
In some situations also a deep copy of the object could be the right solution:
from copy import deepcopy
...
m.append(deepcopy(l))
...
This is a general question that I was not to able to understand.
If I have this:
somelist = [[a for a, b in zip(X, y) if b == c] for c in np.unique(y)]
How can I write this as normal multiline for loop? I never seem to get it right.
EDIT: So far I've tried this:
somelist = []
for c in np.unique(y):
for x, t in zip(X, y):
if t == c:
separated.append(x)
But I wasn't sure if this was right because I wasn't getting an expected result in some other part of my code.
Let me know if this works:
evaluate the outer list comprehension first for the outer loop. then evaluate the inner list comprehension.
somelist=[]
for c in np.unique(y):
ans=[]
for a,b in zip(X,y):
if b==c:
ans.append(a)
somelist.append(ans)
To flat a nested comprehension out, follow these steps:
First create an empty container: somelist = []
If the comprehension has an if clause, put it right after the for
Then, flat the nested comprehensions out, starting with the innermost
The inner comprehension is:
row = []
for a, b in zip(X, y):
if b == c:
row.append(a)
Then, somelist is nothing more than [row for c in np.unique(y)], where row depends on several factors.
This one is equivalent to:
somelist = []
for c in np.unique(y):
somelist.append(row)
So the complete version is:
somelist = []
for c in np.unique(y):
row = []
for a, b in zip(X, y):
if b == c:
row.append(a)
c.append(row)
This how it looks like using "normal" for-loop (a.ka. without using list comprehension):
somelist = []
for c in np.unique(y)
l = []
for a, b in zip(X, y):
if b == c:
l.append(a)
somelist.append(l)
Your were very close. The problem with your approach is that you forgot an important point: The result of the list comprehension will be a list of lists. Thus, the values computed in the inner loop, need to be held in a temporary list that will be append to the "main" list somelist to create a list of lists:
somelist = []
for c in np.unique(y):
# create a temporary list that will holds the values computed in the
# inner loop.
sublist = []
for x, t in zip(X, y):
if t == c:
sublist.append(x)
# after the list has been computed, add the temporary list to the main
# list `somelist`. That way, a list of lists is created.
somelist.append(sublist)
The general rule of thumb when converting a list comprehension to a vanilla for loop is that for each level of nesting, you'll need another nested for loop and another temporary list to hold the values computed in the nested loop.
As a caveat, once you start getting past 2-3 leves of nesting in your comprehension, you should seriously consider coveting it to a normal for loop. Whatever efficacy you're gaining, it offset my the unreliability of the nested list comprehension. Remember, "97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%".
After offering the obvious caveat that, for performance and Pythonic reasons, you should not expand your list comprehension into a multi-line loop, you would write it from the outside in:
somelist = []
for c in np.unique(y):
inner_list = []
for a, b in zip(X, y):
if b == c:
inner_list.append(a)
somelist.append(inner_list)
And now you see the beauty of list comprehensions.
somelist = []
for c in np.unique(y):
somelist.append([a for a, b in zip(X, y) if b == c])
This answer works very well for finding indices of items from a list in another list, but the problem with it is, it only gives them once. However, I would like my list of indices to have the same length as the searched for list.
Here is an example:
thelist = ['A','B','C','D','E'] # the list whose indices I want
Mylist = ['B','C','B','E'] # my list of values that I am searching in the other list
ilist = [i for i, x in enumerate(thelist) if any(thing in x for thing in Mylist)]
With this solution, ilist = [1,2,4] but what I want is ilist = [1,2,1,4] so that len(ilist) = len(Mylist). It leaves out the index that has already been found, but if my items repeat in the list, it will not give me the duplicates.
thelist = ['A','B','C','D','E']
Mylist = ['B','C','B','E']
ilist = [thelist.index(x) for x in Mylist]
print(ilist) # [1, 2, 1, 4]
Basically, "for each element of Mylist, get its position in thelist."
This assumes that every element in Mylist exists in thelist. If the element occurs in thelist more than once, it takes the first location.
UPDATE
For substrings:
thelist = ['A','boB','C','D','E']
Mylist = ['B','C','B','E']
ilist = [next(i for i, y in enumerate(thelist) if x in y) for x in Mylist]
print(ilist) # [1, 2, 1, 4]
UPDATE 2
Here's a version that does substrings in the other direction using the example in the comments below:
thelist = ['A','B','C','D','E']
Mylist = ['Boo','Cup','Bee','Eerr','Cool','Aah']
ilist = [next(i for i, y in enumerate(thelist) if y in x) for x in Mylist]
print(ilist) # [1, 2, 1, 4, 2, 0]
Below code would work
ilist = [ theList.index(i) for i in MyList ]
Make a reverse lookup from strings to indices:
string_indices = {c: i for i, c in enumerate(thelist)}
ilist = [string_indices[c] for c in Mylist]
This avoids the quadratic behaviour of repeated .index() lookups.
If you data can be implicitly converted to ndarray, as your example implies, you could use numpy_indexed (disclaimer: I am its author), to perform this kind of operation in an efficient (fully vectorized and NlogN) manner.
import numpy_indexed as npi
ilist = npi.indices(thelist, Mylist)
npi.indices is essentially the array-generalization of list.index. Also, it has a kwarg to give you control over how to deal with missing values and such.
I created a list of lists and then tried to get a distinct list of the lists using set(), but it appears as though i cant use list on a set.
Is there another way to accomplish this with a concise statement that performs well?
CODE
x = [1,2]
y = [1,2]
z = [2,3]
xyz = []
xyz.append(x)
xyz.append(y)
xyz.append(z)
set(xyz)
Error
TypeError: unhashable type: 'list'
Goal
xyz = [[1,2],[2,3]]
if you want to preserve order and keep your lists, you could use generator function to remove the dupes from your list:
xyz = [x, y, z]
def remove_dupe_subs(l):
seen = set()
for sub in l:
tup = tuple(sub)
if tup not in seen:
yield sub
seen.add(tup)
xyz[:] = remove_dupe_subs(xyz)
Or using a generator expression taking advantage of the fact set.add returns None :
seen = set()
xyz[:] = (seen.add(tup) or sub for sub, tup in zip(xyz, map(tuple, xyz)) if tup not in seen)
print(xyz)
If the list members are hashable, it will work
x = [1,2]
y = [1,2]
z = [2,3]
xyz = []
xyz.append(tuple(x))
xyz.append(tuple(y))
xyz.append(tuple(z))
print xyz
xyz_set = set(xyz)
print xyz_set
It's a little bit convoluted, but this will do the trick in a single line:
xyz=[list(x) for x in list(set((tuple(x),tuple(y),tuple(z))))]
I want to delete the list of tuple in python. I have the list
l = [('name','sam'),('age', 20),('sex', 'male')]
and another list of tuples
r = [('name','sam'),('age', 20)]
I am trying to delete those elements which are in r and l both. I am doing this:
for item in l:
if item in r:
del item
But the elements are not deleting. The output is nothing and when I print the modified list:
>>> l
Then original list is printing.
[('name','sam'),('age', 20),('sex', 'male')]
Please help me, how can I delete elements from list of tuples.
You can tranform both lists in sets and subtract them:
l = [('name','sam'),('age', 20),('sex', 'male')]
r = [('name','sam'),('age', 20)]
The following line will return only the elements that are in l but aren't in r:
set(l) - set(r)
This will return a list of items that are in l and not in r.
The difference between this solution and the solution to substract sets is that you do not lose information if you have duplicates inside your list. You lose this information with substracting sets
difference = [item for item in l if item not in r]
You can use a filter().
for item in filter(lambda x: x not in r, l):
# You can use your items here
# The list gets out of scope, so if there are no other references,
# the garbage collector will destroy it anyway
Or, if you need to use the list elsewhere too, you might also consider creating a new list instead, using a list comprehension:
l = [i for i in l if i not in r]
There are many approaches to go screw this problem:
find AND of those list by l and r for finding which are common in both then use to manipulate this in such a way: [x for x in l if x not in l and r ]. this will be little more efficient than above answers.
Correct marked answer will fall in some cases like what if len(l) < len(r). so for overcome this problem simply
list=[]
p = l and r
list.extend([ [x for x in l if x not in p ], [x for x in r if x not in p ]])
Hope it will fade out some uncovers.