This question already has answers here:
Understanding slicing
(38 answers)
Closed 9 years ago.
my_list = [1,2,3,4,5,6,7,8,9,10,11,12,13]
I need to obtain a specific length of elements form a list starting at a specific index in Python. For instance I would like to get the three next elements from the [2] element above. Is there anyway to get the three elements from the specific index? I wont always know the next amount of elements I want to get, sometimes I may want to get two elements, sometimes eight elements, so x elements.
I know I can do my_list[2:] to get all of the elements from the third element to the end of the list. What I want to do is specify how many elements to read after the third element. Conceptually in my mind the example above would look like my_list[2:+3] however I know this wont work.
How can I achieve this or is it better to define my own function to give me this functionality?
You are actually very close:
>>> my_list = [1,2,3,4,5,6,7,8,9,10,11,12,13]
>>> x = 3
>>> my_list[2:2+x]
[3, 4, 5]
>>>
As you can see, the answer to your question is to slice the list.
The syntax for slicing is list[start:stop:step]. start is where to begin, stop is where to end, and step is what to count by (I didn't use step in my answer).
my_list = [1,2,3,4,5,6,7,8,9,10,11,12,13]
n = 3
print my_list[2:2+n]
Nothing smart here. But, you can pull n out and tweak it the way you want.
you should simply use
my_list[2:2+3]
and in general
list[ STARTING_INDEX : END_INDEX ]
which is equivalent to
list[ STARTING_INDEX : STARTING_INDEX + LENGTH ]
>>> my_list = [1,2,3,4,5,6,7,8,9,10,11,12,13]
>>> my_list[2:3]
[3]
>>> my_list[2:2+3]
[3, 4, 5]
Related
This question already has answers here:
Get max value from a list with lists?
(9 answers)
Closed 4 years ago.
Let's say I have a list:
def returnBiggestStartingList:
L1 = [ [1,2,3,4], [5,6,7,8], [7,8,9,10] ]
I want to return one of the lists inside L1. The one I want to return is the one where the 0th element is the biggest. For example, in the example above I want to return L1[2] because it's first element is higher than the first element of all the other arrays (7 is bigger than 1 and 5).
I also need to account for if the 0th element is the same in one or more lists, if that is the case I would move onto the second element and compare those (so on and so forth)
Anyone know how I can do this?
What you're describing is the natural order of the lists. So you can use max directly, and it's even simpler if all lists have the same size (when the lists have different lengths,
if a list is shorter, it will compare lower to a longer list with same first elements ex: [7,8,9] < [7,8,9,10] which should be OK for your needs too)
L1 = [ [1,2,3,4], [5,6,7,8], [7,8,9,11], [7,8,9,10] ]
print(max(L1))
result:
[7, 8, 9, 11]
You can try this:
def returnBiggestStartingList(L1):
return [i for i in L1 if i[0] == max(zip(*L1)[0])][0]
This question already has answers here:
How can I iterate over overlapping (current, next) pairs of values from a list?
(12 answers)
Why do I get an IndexError (or TypeError, or just wrong results) from "ar[i]" inside "for i in ar"?
(4 answers)
Closed 7 months ago.
Given the following list
a = [0, 1, 2, 3]
I'd like to create a new list b, which consists of elements for which the current and next value of a are summed. It will contain 1 less element than a.
Like this:
b = [1, 3, 5]
(from 0+1, 1+2, and 2+3)
Here's what I've tried:
b = []
for i in a:
b.append(a[i + 1] + a[i])
The trouble is I keep getting this error:
IndexError: list index out of range
I'm pretty sure it occurs because by the time I get the the last element of a (3), I can't add it to anything because doing so goes outside of the value of it (there is no value after 3 to add). So I need to tell the code to stop at 2 while still referring to 3 for the calculation.
In your for loop, you're iterating through the elements of a list a. But in the body of the loop, you're using those items to index that list, when you actually want indexes.
Imagine if the list a would contain 5 items, a number 100 would be among them and the for loop would reach it. You will essentially attempt to retrieve the 100th element of the list a, which obviously is not there. This will give you an IndexError.
We can fix this issue by iterating over a range of indexes instead:
for i in range(len(a))
and access the a's items like that: a[i]. This won't give any errors.
In the loop's body, you're indexing not only a[i], but also a[i+1]. This is also a place for a potential error. If your list contains 5 items and you're iterating over it like I've shown in the point 1, you'll get an IndexError. Why? Because range(5) is essentially 0 1 2 3 4, so when the loop reaches 4, you will attempt to get the a[5] item. Since indexing in Python starts with 0 and your list contains 5 items, the last item would have an index 4, so getting the a[5] would mean getting the sixth element which does not exist.
To fix that, you should subtract 1 from len(a) in order to get a range sequence 0 1 2 3. Since you're using an index i+1, you'll still get the last element, but this way you will avoid the error.
There are many different ways to accomplish what you're trying to do here. Some of them are quite elegant and more "pythonic", like list comprehensions:
b = [a[i] + a[i+1] for i in range(len(a) - 1)]
This does the job in only one line.
Reduce the range of the for loop to range(len(a) - 1):
a = [0, 1, 2, 3]
b = []
for i in range(len(a) - 1):
b.append(a[i] + a[i+1])
This can also be written as a list comprehension:
b = [a[i] + a[i+1] for i in range(len(a) - 1)]
When you call for i in a:, you are getting the actual elements, not the indexes. When we reach the last element, that is 3, b.append(a[i+1]-a[i]) looks for a[4], doesn't find one and then fails. Instead, try iterating over the indexes while stopping just short of the last one, like
for i in range(0, len(a)-1): Do something
Your current code won't work yet for the do something part though ;)
You are accessing the list elements and then using them to attempt to index your list. This is not a good idea. You already have an answer showing how you could use indexing to get your sum list, but another option would be to zip the list with a slice of itself such that you can sum the pairs.
b = [i + j for i, j in zip(a, a[1:])]
This question already has answers here:
Convert string to variable name in python [duplicate]
(3 answers)
Closed 7 years ago.
How can I assign values to variables by using two lists:
Numbers =[1,2,3,4,]
Element= ["ElementA","ElementB","ElementC","ElementD"]
for e, n in zip(Element, Numbers):
e+ ' = ' +n #this part is wrong
What i want is a result like this in the end:
print ElementA
>1
print ElementB
>2
print ElementC
>3
print ElementD
>4
So what im trying to do is to fill up variables created from one list (Element) with values from another list (Numbers) in a kind of loop style.
Does anyone know how to archive something like that?
It should also be possible to assign many values contained in a list/array to variables.
Do not do that.
You're already working with lists, so just create a list instead of hacking some hard-coded names. You could use a dictionary if you really wanted to use identifiers like A, B, etc., but you'd have a problem with more than 26 items, and you're just using it to make a sequence anyway. Integers are great for that, and of course we'll start at 0 because that's how it works.
>>> numbers = [1, 2, 3, 4]
>>> elements = [item for item in numbers]
>>> elements[0]
1
And at this point we can see that, for this example at least, you already had what you were looking for this whole time, in numbers.
>>> numbers = [1, 2, 3, 4]
>>> numbers[0]
1
Perfect.
You may use exec but this is generally the wrong way to go.
for e, n in zip(Element, Numbers):
exec(e + ' = ' + n)
You better should use a dictionnary:
my_dict = {}
for e, n in zip(Element, Numbers):
my_dict[e] = n
Even simpler:
my_dict = dict(zip(Element, Numbers))
This question already has answers here:
How can I make a dictionary (dict) from separate lists of keys and values?
(21 answers)
Closed 6 years ago.
This is code in IDLE2 in python, and error.
I need to include each "data" element as key and value "otro", in an orderly manner. Well "data" and "otro" it's list with 38 string's, as for "dik" it's an dictionary.
>>> for i in range(len(otro)+1):
dik[dato[i]] = otro[i]
Traceback (most recent call last):
File "<pyshell#206>", line 2, in <module>
dik[dato[i]] = otro[i]
IndexError: list index out of range
>>>
this problem is range(0, 38)
output -> (0, 1,2,3 ... 37) and it is all messy
I think something like:
dik = dict(zip(dato,otro))
is a little cleaner...
If dik already exists and you're just updating it:
dik.update(zip(dato,otro))
If you don't know about zip, you should invest a little time learning it. It's super useful.
a = [ 1 , 2 , 3 , 4 ]
b = ['a','b','c','d']
zip(a,b) #=> [(1,'a'),(2,'b'),(3,'c'),(4,'d')] #(This is actually a zip-object on python 3.x)
zip can also take more arguments (zip(a,b,c)) for example will give you a list of 3-tuples, but that's not terribly important for the discussion here.
This happens to be exactly one of the things that the dict "constructor" (type) likes to initialize a set of key-value pairs. The first element in each tuple is the key and the second element is the value.
The error comes from this: range(len(otro)+1). When you use range, the upper value isn't actually iterated, so when you say range(5) for instance, your iteration goes 0, 1, 2, 3, 4, where position 5 is the element 4. If we then took that list elements and said for i in range(len(nums)+1): print nums[i], the final i would be len(nums) + 1 = 6, which as you can see would cause an error.
The more 'Pythonic' way to iterate over something is to not use the len of the list - you iterate over the list itself, pulling out the index if necessary by using enumerate:
In [1]: my_list = ['one', 'two', 'three']
In [2]: for index, item in enumerate(my_list):
...: print index, item
...:
...:
0 one
1 two
2 three
Applying this to your case, you can then say:
>>> for index, item in enumerate(otro):
... dik[dato[index]] = item
However keeping with the Pythonicity theme, #mgilson's zip is the better version of this construct.
This question already has answers here:
How do I remove duplicates from a list, while preserving order?
(31 answers)
Closed 8 months ago.
What I am trying to do is write a method that takes a list as an argument and uses a set to return a copy of the list where each element only occurs once, as well as having the elements in the new list occur in order of their first occurrence in the original list. I HAVE to use a set for this, however, I can't make it so that the output is in the right order while having a quick result.
If I put something like this:
def unique(a):
return list(set(a))
and passed a list with millions of elements, it would give me a result quickly, but it wouldn't be ordered.
So what I have right now is this:
def unique(a):
b = set(a)
c = {}
d = []
for i in b:
c[a.index(i)] = i
for i in c:
d.append(c[i])
return d
This gives me the result I want, but not fast enough. If I pass a list with a million elements, I could be waiting for half an hour, whereas the one liner up there takes less than a second. How could I solve this problem?
>>> from collections import OrderedDict
>>> items = [1, 2, 3, 'a', 2, 4, 'a']
>>> OrderedDict.fromkeys(items).keys()
[1, 2, 3, 'a', 4]