muuh
muuh

Reputation: 1063

Slice tuples within a list (python)

Suppose you have a list of tuples like this:

list_of_tuples = 
    [('11','12','13'),('21','22','23'),('31','32','33'),('41','42','43')]

Now I want to slice this list, or the tuples, so that I have (a new) list, with only the first two entries of each tuple. So, I want to get this:

new_list = [('11','12'),('21','22'),('31','32'),('41','42')]

My first attempt was some syntax like new_list = list_of_tuples[:][0:2]. The first brackets [:] indexing the entire list and [:2] taking element 0 and 1 of each tuple. However, this always returns the first two tuples, containing all three original entries. (So, I get [('11','12','13'),('21','22','23')]).

Why is it not working like this, and what is the underlying pythonic behavior here? I also noted, it does not matter how may [:][:][:] I write.

One way to get my desired results is by writing a list comprehension like this new_list = [(t[0], t[1]) for t in list_of_tuples], but this requires substantially more code and I considered my original approach pythonic as well.

Upvotes: 2

Views: 2634

Answers (6)

S T Mohammed
S T Mohammed

Reputation: 80

Doing iteration into list for tuple slicing a specific items:

Code Syntax

list =  [('11','12','13'),('21','22','23'),('31','32','33'),('41','42','43')]

new_list = [(a[0],a[1]) for a in list]

Output

[('11', '12'), ('21', '22'), ('31', '32'), ('41', '42')]

Upvotes: -1

Pawanvir singh
Pawanvir singh

Reputation: 373

you can use this as well using lambda and map function

new_list  = list(map(lambda x:x[:2],your_list))

Upvotes: 0

Austin
Austin

Reputation: 26039

You can use:

[(x, y) for x, y, _ in list_of_tuples]

Or a slicing with list-comprehension:

[x[:2] for x in list_of_tuples]

Output:

[('11', '12'), ('21', '22'), ('31', '32'), ('41', '42')]

Upvotes: 1

Sijan Bhandari
Sijan Bhandari

Reputation: 3051

You can simply slice the tuple in your first list. Similar to:

>>> list_of_tuples = [('11','12','13'),('21','22','23'),('31','32','33'),('41','42','43')]
>>> new_list = [item[:2] for item in list_of_tuples]
>>> new_list
[('11', '12'), ('21', '22'), ('31', '32'), ('41', '42')]

Upvotes: 2

jpp
jpp

Reputation: 164623

Your logic will not work because slicing does not operate on each sublist within a list. It will only operate on the outer list.

You can use a list comprehension instead:

new_list = [i[:2] for i in list_of_tuples]

Or, for a functional solution, you can use operator.itemgetter:

from operator import itemgetter

new_list = list(map(itemgetter(0, 1), list_of_tuples))

print(new_list)

[('11', '12'), ('21', '22'), ('31', '32'), ('41', '42')]

The syntax you are looking for is akin to NumPy array indexing. NumPy is a 3rd party library which allows indexing by multiple dimensions simultaneously:

import numpy as  np

arr = np.array(list_of_tuples).astype(int)
res = arr[:, :2]

print(res)

[[11 12]
 [21 22]
 [31 32]
 [41 42]]

Upvotes: 3

Mathieu
Mathieu

Reputation: 5746

The first attempt is doing this:

new_list = list_of_tuples[:] # Copy of the list
list_of_tuples[:][0:2] # element 0 to 2 of the copy.

Thus, you get the 2 first element of list_of_tuples:

[('11','12','13'),('21','22','23')]

That's jsut how python works ^^'

EDIT: And if you put several [:] you're just "copying" several time the original list, that's why it doesn't matter how many of this you place...

Upvotes: 2

Related Questions