List of List, want to output variable, not value - python

I have a list of lists like so:
a = [1, 2, 3]
b = [2, 3, 4]
c = []
append blah blah blah
I currently am doing:
for x in c:
print(x)
and it is outputing [1, 2, 3]. How would i get it to output 'a' instead?

There are a few ways to achieve what you want. The first suggestions require using a different data structure. The last suggestion is for demonstration purposes ONLY and should NEVER BE USED.
Option 1. Store you data in a dictionary:
my_data = {"a": [1, 2, 3], "b": [2, 3, 4]}
my_data["c"] = [my_data.get('a'), my_data.get('b')]
Then you would simply iterate over the key, value pairs.
>>> for name, value in my_data.items():
... print name, value
...
a [1, 2, 3]
c [[1, 2, 3], [2, 3, 4]]
b [2, 3, 4]
The dictionary has no useful ordering, so if you wanted it ordered you could use an OrderedDict, or another data structure like a list of tuples.
Or you could sort them before you iterate:
for name, value in sorted(my_data.items()):
print name, value
You could also create the dictionary after the variables are assigned
>>> a = [1, 2, 3]
>>> b = [2, 3, 4]
>>> c = [a, b]
>>> my_data = {"a": a, "b": b, "c": c}
Option Terrible. The very hackish way to do this (and only for demonstration purposes) is to use locals()
>>> a = [1, 2, 3]
>>> b = [2, 3, 4]
>>> c = [a, b]
>>> for name, value in locals().items():
... if len(name) != 1:
... continue
... print name, value
...
a [1, 2, 3]
c [[1, 2, 3], [2, 3, 4]]
b [2, 3, 4]

You are printing a. Your list c is actually
C = [[1,2,3], [2,3,4]]
If you modify a before printing c. The new values in a will be shown. As python passes by reference and c contains a reference to a

If you want to print the variable name see Can I print original variable's name in Python? and How can you print a variable name in python?
However the answers there say you should not do it.
You are telling it to print the complete contents of c which contains the objects a and b which are indeed
[1, 2, 3]
[2, 3, 4]
You are saying that you want to print the string 'a'
To do that you would have to define
c = ['a', 'b']
which is completely different.

Related

Making multiple variables equal to multiple values from a list

Is there a way I can use something like this:
a, b, c = [1, 2, 3, 4, 5]
In order to get the values:
a = 1
b = [2, 3]
c = [4, 5]
To break up existing data as needed:
>>> data = [1,2,3,4,5]
>>> a,b,c = data[0],data[1:3],data[3:]
>>> a
1
>>> b
[2, 3]
>>> c
[4, 5]

How to insert a list at a specific index?

I got a list
a=[1,2,3]
and a list of list
b=[[1,2],[3,4,5]]
and I want to insert a into b at index 1 so b becomes
b=[[1,2],[1,2,3],[3,4,5]]
How do I do that?If I use insert it won't work because I can only insert an item not a list?
EDIT:I realised insert can be used for lists as well.Thanks.
You can use list.insert which takes the index as the first argument
>>> a=[1,2,3]
>>> b=[[1,2],[3,4,5]]
>>> b.insert(1, a)
>>> b
[[1, 2], [1, 2, 3], [3, 4, 5]]
You can use list slicing:
b=[[1,2],[3,4,5]]
a = [1, 2, 3]
final_list = b[:1]+[a]+b[1:]
Output:
[[1, 2], [1, 2, 3], [3, 4, 5]]

Using list comprehension to get a list of entries not in another list, preserving order and quantity

So I have a list, let's say
a = [1, 2, 3, 4, 2, 1, 2, 4]
1 appears twice, 2 appears three times, 4 appears twice. Now I define
b = [4, 2, 2]
Now I want a new list, c, that has the entries of a that are not in b. I tried using list comprehension:
c = [x for x in a if x not in b]
However, this omits the entry if it is in b, rather than seeing how many of each entry are in b and removing that many from a.
c == [1, 3, 1]
I would want it to be
c == [1, 3, 1, 2, 4]
Can anyone provide some help?
You can loop through list b and remove each element from list a:
for i in b:
a.remove(i)
a
# [1, 3, 1, 2, 4]

Python Pandas from dictionary

I have a dictionary
x={'XYZ': [4, 5, 6], 'ABC': [1, 2, 3]}
I want a pd.DataFrame like this:
'SomeColumnName'
'XYZ' [4,5,6]
'ABC' [1,2,3]
Whatever I do, it splits the list of x.values() in 3 separate columns. I could do a '~'.join before creating the Dataframe. Just wondering if there was an easier way
Why don't you just input the data as:
x={'XYZ': [[4, 5, 6]], 'ABC': [[1, 2, 3]]}
Then you get:
In [7]: pd.DataFrame(x).transpose()
Out[7]:
0
ABC [1, 2, 3]
XYZ [4, 5, 6]
You can recode your dictionary using:
for key in x.keys():
x[key] = [x[key]]
Ok, this is how I did it
z = pd.DataFrame.from_records(list(x.items()),columns=['A','SomeColumnName'],index='A')
Problem was - I wasnt using list() for data

Incorrect List manipulation

Let's say
>>> a = [1,2,3,4,5]
And I want an output like
>>> b
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
Here is my code:
class Child(object):
def get_lines(self):
a = [1,2,3,4,5]
b=[]
c=[]
j=0
for i in a:
print i
b.append(i)
print b
c.insert(j,b)
j=j+1
print c
son= Child()
son.get_lines()
When I print list b in loop, it gives:
1
[1]
2
[1, 2]
3
[1, 2, 3]
4
[1, 2, 3, 4]
5
[1, 2, 3, 4, 5]
and the output is:
[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
Where do I make wrong in the code?
b is always the same list object (note I've changed print c to return c):
>>> map(id, Child().get_lines())
...
[49021616, 49021616, 49021616, 49021616, 49021616]
c contains five references to the same list. I think what you want is:
class Child(object):
def get_lines(self):
a = [1, 2, 3, 4, 5]
return [a[:x+1] for x in range(len(a))]
This makes a shallow copy of part (or all) of a for each step:
>>> Child().get_lines()
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
Replace:
c.insert(j,b)
with:
c.append(b[:])
and try again.
You need to make a copy of b. Otherwise you add the same b again and again resulting in the full list at all indices. 'b[:]' copies the list.
This solution does the same but is a bit shorter:
a = [1, 2, 3, 4, 5]
c = []
for i in range(1, len(a) + 1):
c.append(a[:i])
now c is:
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
a[:i] slices the list a from the beginning to excluding the index i.
In this case it does a[:1], a[:2] and so on. a[:1] makes a new list [1],
a[:2] a new list [1, 2,] and so on. Using append() is simpler and insert().
Another alternative is a list comprehension:
a = [1, 2, 3, 4, 5]
[a[:i] for i in range(1, len(a) + 1)]
also results in:
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
Here in this case you are not supposed to append value to the list object (b).
since list is mutable, it will refer to the exact same object in memory until a reassign occurs.
>>> b=[]
>>> b.append(1)
>>> id(b)
4337935424
>>> b.append(2)
>>> id(b)
4337935424
>>> b.append(3)
>>> id(b)
4337935424
>>> b = [1, 2, 3, 4]
>>> id(b)
4337942608
so that in your code c will make five references to the same list.
It will instruct a new object and then (to the extent possible) inserts references into it to the objects found in the original.
>>> class Child(object):
...
... def get_lines(self):
... a = [1, 2, 3, 4, 5]
... return map(lambda x: a[:x+1], range(len(a)))
...
>>> Child().get_lines()
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
You insert same b five times in list c. As a list actually contains references to objects and not copies, you have 5 times a reference to a same b list in which you have added successively 1, 2, 3, 4, 5. So the result.
You must instead add copies of list b :
def get_lines(self):
a = [1,2,3,4,5]
b=[]
c=[]
j=0
for i in a:
print i
b.append(i)
print b
c.insert(j,b[:]) # forces insertion of a copy
j=j+1
print c
In the loop, value of b persists since it's a mutable object. Hence when you print c, the last value of b is shown.
Instead of using b as temporary variable, you can directly use a as follows:
class Child(object):
def get_lines(self):
a = [1,2,3,4,5]
b = []
for index, element in enumerate(a, 1):
b.append(x[:index])
return b
son= Child()
son.get_lines()

Categories