understanding nested list from list with duplicated values [duplicate] - python

This question already has answers here:
How do I get the last element of a list?
(25 answers)
Closed 1 year ago.
To get [[1, 1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]
from old_list = [1,1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]
I found this answer:
new_list = []
for value in old_list:
if new_list and new_list[-1][0] == value:
new_list[-1].append(value)
else:
new_list.append([value])
I am trying to understand what is meaning of new_list[-1][0]
confusion came when I tried to run
new_list = []
new_list[-1] # shows index out of bounds
and new_list and new_list[-1][0] does not produce any error under if statement
What new_list[-1][0] is doing here.

new_list[-1][0] retrieves the last element of new_list, which is itself a list and gets its first element.
new_list and new_list[-1][0] == value short circuits, so it does not try to access the last element if the list is empty.

new_list[-1][0] is checking for the first value in the last element of the list new_list.
Example:
For
new_list = [[1, 1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]]
if you try new_list[-1][0], you will get value 5.
[-1] gets you the last element of the list and [0] gives you the first value.
So, [-1] gets you [5,5,5,5,5] and then [0] gives yoou 5.

Say we tried something on a normal list like this.
new_list = [1,2,3]
print(new_list[-1][0])
We are going to receive an error
print(new_list[-1][0])
TypeError: 'int' object is not subscriptable
But if we try indexing that on lists of a list it will work.
new_list = [[1,2,3],[4,5,6]]
print(new_list[-1][0])
no error, output is
4
Lets take a look into list[-1][0]. Basically, [-1] will get us the last element in a list. In this case it will give us the last list in our bigger list. Then the [0] will get us the first element in a list. So the order is [4,5,6] & 4

Related

how to expand list in list that included in some not-iterable objects to flat? [duplicate]

This question already has answers here:
How to flatten a hetrogenous list of list into a single list in python? [duplicate]
(11 answers)
Closed 1 year ago.
I want to expand list in list that included in some not-iterable
objects to flat.
I tried to do this using list comprehension, but I get an error in not-iterable objects.
How to expand this list to flat?
# [[1, 2], 3] -> [1, 2, 3]
list = [[1, 2], 3]
flat = [item for sublist in list for item in sublist] # TypeError: 'int' object is not iterable
print(flat)
In my environment, numpy is installed in addition to the standard functions.
I tried numpy.concatenate(list).flat, but I get an error.
# [[1, 2], 3] -> [1, 2, 3]
list = [[1, 2], 3]
flat = numpy.concatenate(list).flat # ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 1 dimension(s) and the array at index 1 has 0 dimension(s)
print(flat)
If the iterables are only lists and only one level deep, you can do it in the list comprehension.
L = [[1, 2], 3]
flat = [v for item in L for v in (item if isinstance(item,list) else [item])]
If there are multiple levels and a variety of iterable types, you will probably need a recursive function:
def flatten(L):
if not isinstance(L,(list,tuple,set)): # you probably don't want str here
yield L
return
for F in L:
yield from flatten(F)
L = [[1, 2], 3, ({5,6,7},[8,9],10)]
flat = list(flatten(L))
print(flat)
[1, 2, 3, 5, 6, 7, 8, 9, 10]
You could try this to see if that what's you're looking for:
It can flatten any levels (deeply nested) by recursively calling itself. Just be aware this did not do performance test yet, so there may be room to improve it.
import collections
def flatten(L):
if isinstance(L, collections.Iterable):
return [a for i in L for a in flatten(i)] # recursively calling
else:
return [L]
Running it:
lst = [[1, 2], 3, [[4, 5], 6] ]
print(flatten(lst)) # [1, 2, 3, 4, 5, 6]
lst2 = [[1, 2], 3, [[4, 5, [6]]], 7, 8]
print(flatten(lst2)) # [1, 2, 3, 4, 5, 6, 7, 8] # deeply nested
There may be more elegant solutions, but the trivial one would be to just iterate with a couple of for loops, checking value type:
flat = []
for item in list:
try:
for subitem in item:
flat.append(subitem)
except TypeError: # Not iterable, append as is
flat.append(item)
Note this assumes the nesting is only one level deep.
First of all, I highly recommend avoid identifiers such as list, dict, set etc. as these are data-types from Python and even though the syntax is allowed, you will "hide" them from the usage in your application.
Also, as a suggestion, avoid using list comprehension for more complex operations, as they can become difficult to read.
I recommend the following approach:
my_list = [[1, 2], 3]
flat = []
for item in my_list:
if isinstance(item, list):
for val in item:
flat.append(val)
else: flat.append(item)
print(flat)
Using list comprehension, the solution would look like:
my_list = [[1, 2], 3]
flat = [v for item in my_list for v in (item if isinstance(item,list) else [item])]
print(flat)

Python Slicing Issue: every other element in list, starting with last element not working?

so I have a list of numbers, and I want to start at the last element of the list and print every other element.
So given list = [1, 2, 3, 4, 5, 6] I would print 6, 4 and 2. My issue is that slicing is not printing the last element.
list = [1, 2, 3, 4, 5, 6]
for i in list[-1::-2]:
print(list[i])
this merely prints 4 and 2, showing me that the last digit is not included. I have also tried omitting the -1 and just using list[::-2]. It takes every odd digit (4 and 2) but does not include 6. I want to use slicing to achieve this result, but clearly I am misunderstanding how to use it. Any help much appreciated (this is my first stackOverflow question btw!)
Please avoid using the variable names as a list.
ls = [1, 2, 3, 4, 5, 6]
for i in ls[-1::-2]:
print(i)
You're iterating all the elements of the list using the in method. It doesn't provide you an index that you will use to print.
When you're trying to print list[i] it will raise an error because when i=6 then list[i] element don't exist in the list.
You can simply do slicing by using:
ls = [1, 2, 3, 4, 5, 6]
print(ls[-1::-2])
and don't use the list as a variable name because it is a keyword in Python so you will get an error.
Have you tried printing just i instead of the list[i]?
You should remember here that if you iterate through a reversed list, you need not do indexing again. The i would hold the value of the list element.
Please try:
for i in ls[::-2]:
print(i)

Python how do you get the index of a list in a list, by knowing the first element of the list in lists?

Imagine the list [[0, 1],[2, 3][4, 5]],
how can I get the index of the list [2,3] (which is supposed to be 1), by knowing the number 2. In code something like:
in a list of lists, find the index of the list where list[0] == 2.
This should return 1.
You can do this using a for loop. So for example:
nums = [[0, 1],[2, 3],[4, 5]]
for index, num_list in enumerate(nums):
if num_list[0] == 2:
print(index)
You could use the next function on an enumeration of the list that would return the index of matching items
aList = [[0, 1],[2, 3],[4, 5]]
index = next(i for i,s in enumerate(aList) if s[0]==2)
print(index) # 1
or, if you're not concerned with performance, using a more compact way by building a list of the first elements of each sublist and using the index() method on that:
index = [*zip(*aList)][0].index(2)
or
index = [i for i,*_ in aList].index(2)
Iterate through the list and check the value of the first element. Use a variable to track which index you're looking at.
for i in list:
if i[0]==2:
print(list.index(i))
Check Kaggle python course for such practical exercises
https://www.kaggle.com/learn/python
Since index method only supports exact value comparison, you need to iterate. See this question:
Python: return the index of the first element of a list which makes a passed function true
array = [[0, 1],[2, 3],[4, 5]]
def get_index(array):
i = 0
for element in array:
if(element[0]==2):
break
i+=1
return i
print(str(get_index(array)))
If you have lots of such queries to make, it might be more efficient to build a dict first, with the first value of each sublist as key and the sublist as value:
data = [[0, 1], [2, 3], [4, 5]]
data_by_first_value = {lst[0]: lst for lst in data}
This dict will look like:
print(data_by_first_value)
# {0: [0, 1], 2: [2, 3], 4: [4, 5]}
It is then an O(1) operation to get the sublist you're looking for:
print(data_by_first_value[2])
# [2, 3]

how to remove the last digit in a list if the list contain number last number some were in the list

i need to remove a digit in the given list,But while executing this first digit is removed
python pycharm
l = [4, 2, 6, 4, 7]
l.remove(l[3])
print(l)
expected output:[4, 2, 6, 7]
But I get: [2, 6, 4, 7]
To remove an item from a list given an index, use list().pop() like so:
l.pop(3) # Remove the third element.
It has 3 methods to remove an element from python List.
You can read more about list in here
list.pop(3) # remove 4th element
del list(3) # remove 4th element
list.remove(value1) # remove element have value1 in list
Avoid using a direct pop() function if your list is dynamically generating because you don't know the index of elements.
The enumerate() function adds a counter to an iterable.
So for each element in a cursor, a tuple is produced with (counter, element).
list1 = [4, 2, 6, 4, 7]
new_list = []
for index,elm in enumerate(list1):
if elm not in (list1[:index]):
new_list.append(elm)
print(new_list)
O/P:
[4, 2, 6, 7]

Slicing a list with variable chunk size in Python [duplicate]

This question already has answers here:
Understanding slicing
(38 answers)
Closed 5 years ago.
I worked in Python 3.6, and I am a beginner. So can anyone give me a true way of how can slice a list into variable size sub-list. I tried this solution from this site, but it gave me fixed size of sliced list. To clarify:
if I have this list:
inputList= [0,1,2,3,4,5,6,7]
I want the output to be like e.g.:
outputList=[[0,1,2], [3,4], [5], [6,7]]
each time it depends on (for example) user input or some variable size.
Just use itertools.islice(). This has the added advantage that if you request a slice that you would normally take you out of bounds, you won't get an error. You'll just get as many items are left as possible.
>>> import itertools as it
>>> input_list = range(8)
>>> slices = (3, 2, 1, 2)
>>> iterable = iter(input_list)
>>> output_list = [list(it.islice(iterable, sl)) for sl in slices]
>>> output_list
[[0, 1, 2], [3, 4], [5], [6, 7]]
For example, if you had slices = (3, 2, 1, 3, 2), your result would be [[0, 1, 2], [3, 4], [5], [6, 7], []].
Basically, iter(input_list) creates an iterable of your list so you can fetch the next k values with islice().
You can do this in a loop making use of python's [:#] slice notation:
Let's say the user's input for slicing chunk sizes is stored in a list. They want chunks of 3, 2, 1 and 2, so the user input defining the chunks gets stored into a list that has has [3,2,1,2].
Then, loop through that list and use it to get your slices:
input_list = [0,1,2,3,4,5,6,7]
chunk_list = [3,2,1,2]
output_list = []
for i in chunk_list:
output_list.append(input_list[:i])
input_list = input_list[i:]
print(output_list)
Prints:
[[0, 1, 2], [3, 4], [5], [6, 7]]
Probably you just want to learn about slicing. See Understanding Python's slice notation
To get your example output, you could do
outputList = [inputList[:3], inputList[3:5], inputList[5:6], inputList[6:]]

Categories

Resources