Say, I have a list of values:
>>> a = [1, 2, 3, 4]
How can I make it include the end value through slicing? I expected:
>>> a[4:]
[4]
instead of:
>>> a[4:]
[]
Slicing indices start from zero
So if you have:
>>> xs = [1, 2, 3, 4]
| | | |
V V V V
0 1 2 3 <-- index in xs
And you slice from 4 onwards you get:
>>> xs[4:]
[]
Four is is the length of ``xs`, not the last index!
However if you slice from 3 onwards (the last index of the list):
>>> xs[3:]
[4]
See: Data Structures
Many many common computer programmming langauges and software systems are in fact zero-based so please have a read of Zero-based Numbering
Python indexes are zero based. The last element is at index 3, not 4:
>>> a = [1,2,3,4]
>>> a[3:]
[4]
a = [1,2,3,4]
a[-1:]
In python you can iterate values from beginning to end ending to beginning
1, 2, 3, 4
| | | |
0 1 2 3 (or)
-4 -3 -2 -1
So If you want last element of the list you can use either a[len(a)-1:] or a[-1:]
Related
I encountered something I don't understand. I created a simple example in order to explain it. I have the following list:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
I iterate through the list, printing the value at the current index, and remove the value if it is even. This results in the next value getting skipped because they all move up one index (filling the gap created by the removal).
for i in numbers:
print(i)
if i % 2 == 0:
numbers.remove(i)
This results in the following output, which is as expected:
1
2
4
6
8
10
When iterating through the list backwards, this problem will be avoided, since all the lower indexes won't be affected by the removal of a higher index.
for i in numbers[::-1]:
print(i)
if i % 2 == 0:
numbers.remove(i)
Which results in (as expected):
10
9
8
7
6
5
4
3
2
1
Now we've arrived at the part I don't understand. As far as I know the default stepsize is 1, so adding [::1] shouldn't make any difference right? Well, it does...
for i in numbers[::1]:
print(i)
if i % 2 == 0:
numbers.remove(i)
Which results in:
1
2
3
4
5
6
7
8
9
10
As yous see all the numbers are getting printed, while I expected some to be skipped due to the shifting explained earlier.
Can someone explain why this is?
So, the answer is already there in the comments, just a proper explanation here:
Basically, when you say:
for i in numbers:
print(i)
if i % 2 == 0:
numbers.remove(i)
You are iterating through the list numbers
But when you write:
for i in numbers[::1]:
print(i)
if i % 2 == 0:
numbers.remove(i)
It can be seen as an equivalent to:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# <-------------
num2 = numbers.copy() #or numbers[::1] <-------------- |
# i.e. python automatically creates a copy of the | |
# list numbers to iterate through | |
# since it seems like you are iterating through a | |
# slice of the original list | |
# | |
for i in numbers[::1]: # iterates through------------- |
print(i) # |
if i % 2 == 0: # |
numbers.remove(i) # this removes elements from --
The difference? The copy created is only stored until iteration is done. Hence even when the elements are removed, since the current list is the same, no number is skipped.
How to count number of values repeated in list at first position and do sum based on that
My input :
[[2, 1], [2, 1], [2, 1], [1, 2]]
Note : my list will contain 2 OR 1 in first index[0]
In above the 2 is repeated the maximum number of times so my sum should be like get its second value of all and do sum and display
2 , 1 -> 1 +
2 , 1 -> 1 +
2 , 1 -> 1
----------------------
2 , 3
So output would be : 2 , 3
How to achieve above output from given Input
In my code not able to implement such logic
cnt=0
m[0]=0
for m in my_list:
if m[0] == 2
cnt+=1
v=m[1]
print(m[0],v[1])
Try:
#create a list with just the 0th elements
keys = [i[0] for i in l]
#get the key that has the maximum count
max_key = max(keys, key=keys.count)
#sum the 1st element for all sublists where the 0th element is the same as the max_key
>>> max_key, sum(i[1] for i in l if i[0]==max_key)
(2, 3)
In one line (not recommended as it's not very readable):
>>> max([i[0] for i in l], key=[i[0] for i in l].count), sum(i[1] for i in l if i[0]==max([i[0] for i in l], key=[i[0] for i in l].count))
(2, 3)
Suppose we know 2 is the most common 1st item, here's a one liner list comprehension to make the sum:
[2, sum(x[1] for x in l if x[0]==2)]
# ^ ^ ^
# | | \-- if 1st item is 2
# | \-- extract 2nd item
# \-- sum all the 2nd items
To find the most common 1st item, we can use collections.Counter:
from collections import Counter
Counter(x[0] for x in l).most_common(1) # [(2, 3)]
Put everything together:
n = Counter(x[0] for x in l).most_common(1)[0][0]
[n, sum(x[1] for x in l if x[0]==n)] # [2, 3]
I have:
hi
0 1
1 2
2 4
3 8
4 3
5 3
6 2
7 8
8 3
9 5
10 4
I have a list of lists and single integers like this:
[[2,8,3], 2, [2,8]]
For each item in the main list, I want to find out the index of when it appears in the column for the first time.
So for the single integers (i.e 2) I want to know the first time this appears in the hi column (index 1, but I am not interested when it appears again i.e index 6)
For the lists within the list, I want to know the last index of when the list appears in order in that column.
So for [2,8,3] that appears in order at indexes 6, 7 and 8, so I want 8 to be returned. Note that it appears before this too, but is interjected by a 4, so I am not interested in it.
I have so far used:
for c in chunks:
# different method if single note chunk vs. multi
if type(c) is int:
# give first occurence of correct single notes
single_notes = df1[df1['user_entry_note'] == c]
single_notes_list.append(single_notes)
# for multi chunks
else:
multi_chunk = df1['user_entry_note'].isin(c)
multi_chunk_list.append(multi_chunk)
You can do it with np.logical_and.reduce + shift. But there are a lot of edge cases to deal with:
import numpy as np
def find_idx(seq, df, col):
if type(seq) != list: # if not list
s = df[col].eq(seq)
if s.sum() >= 1: # if something matched
idx = s.idxmax().item()
else:
idx = np.NaN
elif seq: # if a list that isn't empty
seq = seq[::-1] # to get last index
m = np.logical_and.reduce([df[col].shift(i).eq(seq[i]) for i in range(len(seq))])
s = df.loc[m]
if not s.empty: # if something matched
idx = s.index[0]
else:
idx = np.NaN
else: # empty list
idx = np.NaN
return idx
l = [[2,8,3], 2, [2,8]]
[find_idx(seq, df, col='hi') for seq in l]
#[8, 1, 7]
l = [[2,8,3], 2, [2,8], [], ['foo'], 'foo', [1,2,4,8,3,3]]
[find_idx(seq, df, col='hi') for seq in l]
#[8, 1, 7, nan, nan, nan, 5]
I know that the order of the keys is not guaranteed and that's OK, but what exactly does it mean that the order of the values is not guaranteed as well*?
For example, I am representing a matrix as a dictionary, like this:
signatures_dict = {}
M = 3
for i in range(1, M):
row = []
for j in range(1, 5):
row.append(j)
signatures_dict[i] = row
print signatures_dict
Are the columns of my matrix correctly constructed? Let's say I have 3 rows and at this signatures_dict[i] = row line, row will always have 1, 2, 3, 4, 5. What will signatures_dict be?
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
or something like
1 2 3 4 5
1 4 3 2 5
5 1 3 4 2
? I am worried about cross-platform support.
In my application, the rows are words and the columns documents, so can I say that the first column is the first document?
*Are order of keys() and values() in python dictionary guaranteed to be the same?
You will guaranteed have 1 2 3 4 5 in each row. It will not reorder them. The lack of ordering of values() refers to the fact that if you call signatures_dict.values() the values could come out in any order. But the values are the rows, not the elements of each row. Each row is a list, and lists maintain their order.
If you want a dict which maintains order, Python has that too: https://docs.python.org/2/library/collections.html#collections.OrderedDict
Why not use a list of lists as your matrix? It would have whatever order you gave it;
In [1]: matrix = [[i for i in range(4)] for _ in range(4)]
In [2]: matrix
Out[2]: [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
In [3]: matrix[0][0]
Out[3]: 0
In [4]: matrix[3][2]
Out[4]: 2
I have a string a="1 2 3; 4 5 6". How do i express this as a matrix [1 2 3; 4 5 6] in Python?
I want to then use another such string b, convert to a matrix and find a x b.
You can use the numpy module to create a matrix directly from a string in matlab type format
>>> import numpy as np
>>> a="1 2 3; 4 5 6"
>>> np.matrix(a)
matrix([[1, 2, 3],
[4, 5, 6]])
You can use the same library to do matrix multiplication
>>> A = np.matrix("1 2 3; 4 5 6")
>>> B = np.matrix("2 3; 4 5; 6 7")
>>> A * B
matrix([[28, 34],
[64, 79]])
Go read up on the numpy library, it is a very powerful module to do all of the type of work that you are referring to.
This is one way to do it, split the string at ;, then go through each string, split at ' ' and then go through that, convert it to an int and append to a sublist, then append that sublist to another list:
a = "1 2 3; 4 5 6"
aSplit = a.split('; ')
l = []
for item in aSplit:
subl = []
for num in item.split(' '):
subl.append(int(num))
l.append(subl)
print l