I am a complete newbie to Python and am completely stuck. Basically, I have information in a list like the one below:
[a, b, c, d]
[e, f, g, h, i]
and so on....
From each list I want to get the second and the final data, so that it will return the following
b,d
f,i
I have been looking at using the sort() function or the split() function but to be honest I have no idea where to start.
Please can someone help me or point me in the right direction?
for lis in lists:
print(lis[1], lis[-1])
Where [1] gives the second element and [-1] gives the last. List indices start at 0, which is why [1] gives the second element. Negative indices are valid as well, and starting from -1, they count backwards from the end of the list. Negative indices are especially useful when dealing with lists of variable lengths.
In your case lists would be [[a, b, c, d], [e, f, g, h, i]].
You should do this:
# Assuming the letters below actually have values,
# otherwise you must make these characters
mylist = [a,b,c,d]
secondElement = mylist[1]
lastElement = mylist[-1]
list[-1] will return the last element of the list, and list[1] will return the second element of the list
something like
>>>a = [1,2,3,4]
>>>b = [5,6,7,8]
>>>print a[1],a[-1]
4,2
>>>print b[1],b[-1]
6,8
index from left: 0, 1, 2, 3
list : [5, 2, 2, 4]
index fro right: -4,-3,-2,-1
Related
I have some data looks like in this format
2,3,4
3,4,5
5,6,7
I pack the array as:
with open('house_price_data.txt') as data:
substrings = data.read().split()
array = [map(int, substring.split(',')) for substring in substrings]
My task is to do some calculation like this for each data in the set:
(2-3)**2 + (3-3)**2 + (5-3)**2
(3-4)**2 + (4-4)**2 + (5-4)**2
My expected answer is C1 = 5 and C2 = 2
I wrote a code like this
for [a for a, b, c in array] in range (0,2):
C1 = (([a for a, b, c in array]) - 3)**2
C2 = (([b for a, b, c in array]) - 4)**2
But it is not working. For the purpose of for loop, I think it will read the data 2,3,5 one by one minus 3 and square the result one by one and sum the total results. So how can I improve it?
A part from that, I also have problems with this code
[a for a, b, c in array]
[b for a, b, c in array]
[c for a, b, c in array]
I need to call array many times with this code with item a, b and c of the array in the program, when I have such codes in the program error massage come
not enough values to unpack (expected 3, got 0)
How can I do to make changes?
This question is unclear and probably destined for oblivion, but if I understand correctly, which is far from certain, you are trying to do something like this.
array = [[2, 3, 5], [3, 4, 5], [5, 6, 7]]
#initialize the variables C1 and C2
C1 = 0
C2 = 0
#iterate the elements of the FIRST list in your list
#so 2,3,5 (I assume you have indicated 2,3,4 by mistake)
for element in array[0]:
C1+=(element-3)**2
#iterate the elements of the SECOND list in your list
#so 3,4,5
for element in array[1]:
C2+=(element-4)**2
print("C1 =", C1)
print("C2 =", C2)
Output:
C1 = 5
C2 = 2
But your example is ambiguous. Maybe 2,3,5 are the first elements in each sublist ? In this case, the logic is the same.
#iterate the FIRST element in each sublist in your list
for element in array:
C1+=(element[0]-3)**2
If that's what you want to do, then it's best for you to do it like that, with classic loops. List comprehensions (things like [x for x in array if ...]) are shortcuts for advanced Python programmers. They do exactly the same thing, but are less clear and more error prone.
If you have array = [[2,3,4],[3,4,5],[5,6,7]], then you want a = [2,3,5], then that would be
a = [x[0] for x in array]
Otherwise, array[0] is [2,3,4] and you can instead do
a, b, c = array
To unpack the 2D array.
Sidenote: you seem to have a CSV file, so I would strongly suggest using Pandas and Numpy for your numerical calculations
I need to find the smallest value in a series of lists. I understand the code for the smallest value in just one list:
>>> x = [1, 2, 3, 4, 5]
>>> print (min(x))
1
Simple enough. However, I would like to know if there is a way to write code that finds the smallest value for each list I have without stopping and adjusting the code (whether by an iterative process or some other means). Any help would be greatly appreciated. Thanks in advance!
First, make a list of lists out of your separate lists. For example, if you have lists A, B and C, the list of lists would be [A,B,C].
Now, to get a list of all the minimum values for each list in a list of lists lst:
[min(x) for x in lst]
To get the global minimum:
min(x for sublist in lst for x in sublist)
Demo:
>>> lst
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> [min(x) for x in lst]
[1, 4, 7]
>>> min(x for sublist in lst for x in sublist)
1
Edit in reaction to OP's comment:
I just want the minimum value for each list. I don't need to compile all of the minimum values together into a new list
If you just want to print the minimum values for each list A, B, C, ... , you can do:
for lst in (A,B,C): # put as many lists as you like into the parentheses
print(min(lst))
Edit in reaction to
I am only accessing one list (in this case, the values are well depths) at a time. [..] What I would like to know is how to write a code that finds the smallest value in a list given that the iterator essentially changes the values in said list.
Just print(min(lst)) each time lst has changed.
Assuming you've got a list of lists, this should do it:
minimums = [min(l) for l in lists]
I want to build some lists (a, b, c, d) by extending periodically those given in input.
The structure of the periodicity is such that the first element of each list must not be repeated, while all the other elements must be until the maximum length set in input is reached (it is possible that the period does not get to be repeated an integer number of times).
To give an example, if I have as input
a = [1, 2, 3, 4] max_len=11
I want to obtain as output
a = [1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2]
I wrote this piece of code:
for mylist in [a, b, c d]:
period = mylist[1:] # all elements but the first are repeated
while len(mylist)< max_len:
mylist.extend(period)
mylist = mylist[:max_len] # cut to max_len
print mylist
print a, b, c, d
If I run this, I see from the two print commands that my lists are how I want them to be while the program is still in the loop, but they get back to the "non-sliced" length when out of the loop, that is, a gets back to the length greater than max_len where the period is repeated exactly 4 times:
a = [1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4]
Why is that? It looks like the program has forgotten the slicing (but not the extension).
I understand that it is a pretty simple problem, and I could get around it in some other way, but I would like to understand why this idea does not work.
Thank you for your help!
The problem is that mylist = mylist[:max_len] creates a new list instead of modifying mylist in place, so the results never propagate back to a et al.
If you replace:
mylist = mylist[:max_len]
with
mylist[:] = mylist[:max_len]
that'll fix it.
As an aside, you could use itertools for the transformation:
In [10]: [a[0]] + [v for v in itertools.islice(itertools.cycle(a[1:]), max_len - 1)]
Out[10]: [1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2]
mylist in the loop starts off referring to one of the input lists such as a but when you assign to it you are just rebinding the name mylist to a new list, you are not modifying the original list.
This would work:
for mylist in [a, b, c, d]:
period = mylist[1:] # all elements but the first are repeated
while len(mylist)< max_len:
mylist.extend(period)
mylist[:] = mylist[:max_len] # cut to max_len
print mylist
print a, b, c, d
The slice assignment updates the original list.
Or you could try this, just updating the original list once:
for mylist in [a, b, c, d]:
mylist[1:] = (mylist[1:] * (1+max_len//(len(mylist)-1)))[:max_len]
print(mylist)
print a, b, c, d
I have few lists like:
a = [1, 2, 3, 4, 5]
b = [4, 6, 5, 9, 2]
c = [4, 7, 9, 1, 2]
I want to trim all of them using a loop, instead of doing as below:
a[-2:]
b[-2:]
c[-2:]
I tried but got confused with pass by value or pass by reference fundamentals, looked into other questions as well but no help.
Thanks
for l in [a, b, c]:
del l[-2:]
This removes the last two elements from each list. If you want to remove all but the last two elements only, do this:
for l in [a, b, c]:
del l[:-2]
There's no need to worry about references here; the list over which the for loop iterates contains references to a, b and c, and each list is mutated in-place by deleting a list slice.
x = [a, b, c]
x = map(lambda lst: lst[-2:], x)
Deleting the unwanted items from the existing lists, using a loop:
for list in [a, b, c]:
del a[:-2]
Or, creating new lists containing only the correct items, using a list comprehension:
(a, b, c) = [x[-2:] for x in (a, b, c)]
This question already has answers here:
How can I use list comprehensions to process a nested list?
(13 answers)
Closed last month.
In Python you can have multiple iterators in a list comprehension, like
[(x,y) for x in a for y in b]
for some suitable sequences a and b. I'm aware of the nested loop semantics of Python's list comprehensions.
My question is: Can one iterator in the comprehension refer to the other? In other words: Could I have something like this:
[x for x in a for a in b]
where the current value of the outer loop is the iterator of the inner?
As an example, if I have a nested list:
a=[[1,2],[3,4]]
what would the list comprehension expression be to achieve this result:
[1,2,3,4]
?? (Please only list comprehension answers, since this is what I want to find out).
Suppose you have a text full of sentences and you want an array of words.
# Without list comprehension
list_of_words = []
for sentence in text:
for word in sentence:
list_of_words.append(word)
return list_of_words
I like to think of list comprehension as stretching code horizontally.
Try breaking it up into:
# List Comprehension
[word for sentence in text for word in sentence]
Example:
>>> text = (("Hi", "Steve!"), ("What's", "up?"))
>>> [word for sentence in text for word in sentence]
['Hi', 'Steve!', "What's", 'up?']
This also works for generators
>>> text = (("Hi", "Steve!"), ("What's", "up?"))
>>> gen = (word for sentence in text for word in sentence)
>>> for word in gen: print(word)
Hi
Steve!
What's
up?
To answer your question with your own suggestion:
>>> [x for b in a for x in b] # Works fine
While you asked for list comprehension answers, let me also point out the excellent itertools.chain():
>>> from itertools import chain
>>> list(chain.from_iterable(a))
>>> list(chain(*a)) # If you're using python < 2.6
Gee, I guess I found the anwser: I was not taking care enough about which loop is inner and which is outer. The list comprehension should be like:
[x for b in a for x in b]
to get the desired result, and yes, one current value can be the iterator for the next loop.
Order of iterators may seem counter-intuitive.
Take for example: [str(x) for i in range(3) for x in foo(i)]
Let's decompose it:
def foo(i):
return i, i + 0.5
[str(x)
for i in range(3)
for x in foo(i)
]
# is same as
for i in range(3):
for x in foo(i):
yield str(x)
ThomasH has already added a good answer, but I want to show what happens:
>>> a = [[1, 2], [3, 4]]
>>> [x for x in b for b in a]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
>>> [x for b in a for x in b]
[1, 2, 3, 4]
>>> [x for x in b for b in a]
[3, 3, 4, 4]
I guess Python parses the list comprehension from left to right. This means, the first for loop that occurs will be executed first.
The second "problem" of this is that b gets "leaked" out of the list comprehension. After the first successful list comprehension b == [3, 4].
This memory technic helps me a lot:
[ <RETURNED_VALUE> <OUTER_LOOP1> <INNER_LOOP2> <INNER_LOOP3> ... <OPTIONAL_IF> ]
And now you can think about Return + Outer-loop
as the only Right Order
Knowing above, the order in list comprehensive even for 3 loops seem easy:
c=[111, 222, 333]
b=[11, 22, 33]
a=[1, 2, 3]
print(
[
(i, j, k) # <RETURNED_VALUE>
for i in a for j in b for k in c # in order: loop1, loop2, loop3
if i < 2 and j < 20 and k < 200 # <OPTIONAL_IF>
]
)
[(1, 11, 111)]
because the above is just a:
for i in a: # outer loop1 GOES SECOND
for j in b: # inner loop2 GOES THIRD
for k in c: # inner loop3 GOES FOURTH
if i < 2 and j < 20 and k < 200:
print((i, j, k)) # returned value GOES FIRST
for iterating one nested list/structure, technic is the same:
for a from the question:
a = [[1,2],[3,4]]
[i2 for i1 in a for i2 in i1]
which return [1, 2, 3, 4]
for one another nested level
a = [[[1, 2], [3, 4]], [[5, 6], [7, 8, 9]], [[10]]]
[i3 for i1 in a for i2 in i1 for i3 in i2]
which return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
and so on
I could never write double list comprehension on my first attempt. Reading into PEP202, it turns out the reason is that it was implemented in the opposite way you would read it in English. The good news is that it is a logically sound implementation, so once you understand the structure, it's very easy to get right.
Let a, b, c, d be successively nested objects. For me, the intuitive way to extend list comprehension would mimic English:
# works
[f(b) for b in a]
# does not work
[f(c) for c in b for b in a]
[f(c) for c in g(b) for b in a]
[f(d) for d in c for c in b for b in a]
In other words, you'd be reading from the bottom up, i.e.
# wrong logic
(((d for d in c) for c in b) for b in a)
However this is not how Python implements nested lists. Instead, the implementation treats the first chunk as completely separate, and then chains the fors and ins in a single block from the top down (instead of bottom up), i.e.
# right logic
d: (for b in a, for c in b, for d in c)
Note that the deepest nested level (for d in c) is farthest from the final object in the list (d). The reason for this comes from Guido himself:
The form [... for x... for y...] nests, with the last index varying fastest, just like nested for loops.
Using Skam's text example, this becomes even more clear:
# word: for sentence in text, for word in sentence
[word for sentence in text for word in sentence]
# letter: for sentence in text, for word in sentence, for letter in word
[letter for sentence in text for word in sentence for letter in word]
# letter:
# for sentence in text if len(sentence) > 2,
# for word in sentence[0],
# for letter in word if letter.isvowel()
[letter for sentence in text if len(sentence) > 2 for word in sentence[0] for letter in word if letter.isvowel()]
If you want to keep the multi dimensional array, one should nest the array brackets. see example below where one is added to every element.
>>> a = [[1, 2], [3, 4]]
>>> [[col +1 for col in row] for row in a]
[[2, 3], [4, 5]]
>>> [col +1 for row in a for col in row]
[2, 3, 4, 5]
I feel this is easier to understand
[row[i] for row in a for i in range(len(a))]
result: [1, 2, 3, 4]
Additionally, you could use just the same variable for the member of the input list which is currently accessed and for the element inside this member. However, this might even make it more (list) incomprehensible.
input = [[1, 2], [3, 4]]
[x for x in input for x in x]
First for x in input is evaluated, leading to one member list of the input, then, Python walks through the second part for x in x during which the x-value is overwritten by the current element it is accessing, then the first x defines what we want to return.
This flatten_nlevel function calls recursively the nested list1 to covert to one level. Try this out
def flatten_nlevel(list1, flat_list):
for sublist in list1:
if isinstance(sublist, type(list)):
flatten_nlevel(sublist, flat_list)
else:
flat_list.append(sublist)
list1 = [1,[1,[2,3,[4,6]],4],5]
items = []
flatten_nlevel(list1,items)
print(items)
output:
[1, 1, 2, 3, 4, 6, 4, 5]