95

I'm working on a script where I have a list of tuples like ('1','2','3','4'). e.g.:

list = [('1','2','3','4'),
        ('2','3','4','5'),
        ('3','4','5','6'),
        ('4','5','6','7')]

Now I need to add '1234', '2345','3456' and '4567' respectively at the end of each tuple. e.g:

list = [('1','2','3','4','1234'),
        ('2','3','4','5','2345'),
        ('3','4','5','6','3456'),
        ('4','5','6','7','4567')]

Is it possible in any way?

atp
  • 30,132
  • 47
  • 125
  • 187
Shahzad
  • 951
  • 1
  • 6
  • 3
  • 3
    At least in Python, tuples are immutable. If you want to "add something to a tuple", why not use a mutable data structure from the start? – Felix Kling Feb 06 '11 at 12:54
  • 2
    I do it too -- most often with "file", because "for file in files" is so darn natural! -- but in general you should probably avoid calling your lists "list", which replaces the built-in "list". – DSM Feb 06 '11 at 13:06

11 Answers11

169

Tuples are immutable and not supposed to be changed - that is what the list type is for.

However, you can replace each tuple using originalTuple + (newElement,), thus creating a new tuple. For example:

t = (1,2,3)
t = t + (1,)
print(t)
(1,2,3,1)

But I'd rather suggest to go with lists from the beginning, because they are faster for inserting items.

And another hint: Do not overwrite the built-in name list in your program, rather call the variable l or some other name. If you overwrite the built-in name, you can't use it anymore in the current scope.

Pikamander2
  • 7,332
  • 3
  • 48
  • 69
AndiDog
  • 68,631
  • 21
  • 159
  • 205
  • 25
    A shorthand `t += 1,` –  Aug 26 '13 at 21:54
  • 2
    Excellent points, however, I am in the unfortunate situation where I want to iteratively add values to a `sqlite3` database and need to make a tuple of the values to add (since the required syntax is `VALUES (v1, v2, v3, ...)`. In this case, knowing how to add values to a tuple is very beneficial. – m13op22 Apr 15 '19 at 03:12
17

Based on the syntax, I'm guessing this is Python. The point of a tuple is that it is immutable, so you need to replace each element with a new tuple:

list = [l + (''.join(l),) for l in list]
# output:
[('1', '2', '3', '4', '1234'), 
 ('2', '3', '4', '5', '2345'), 
 ('3', '4', '5', '6', '3456'), 
 ('4', '5', '6', '7', '4567')]
atp
  • 30,132
  • 47
  • 125
  • 187
  • 5
    This works, sure. But should this really be done? I wonder. Because this defeats the purpose of having a tuple in the first place. Or am I wrong? – user225312 Feb 06 '11 at 13:04
11

As mentioned in other answers, tuples are immutable once created, and a list might serve your purposes better.

That said, another option for creating a new tuple with extra items is to use the splat operator:

new_tuple = (*old_tuple, 'new', 'items')

I like this syntax because it looks like a new tuple, so it clearly communicates what you're trying to do.

Using splat, a potential solution is:

list = [(*i, ''.join(i)) for i in list]

Terrabits
  • 997
  • 2
  • 15
  • 19
9

In Python, you can't. Tuples are immutable.

On the containing list, you could replace tuple ('1', '2', '3', '4') with a different ('1', '2', '3', '4', '1234') tuple though.

Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
8

As other people have answered, tuples in python are immutable and the only way to 'modify' one is to create a new one with the appended elements included.

But the best solution is a list. When whatever function or method that requires a tuple needs to be called, create a tuple by using tuple(list).

Ryan
  • 91
  • 2
5

I was going through some details related to tuple and list, and what I understood is:

  • Tuples are Heterogeneous collection data type
  • Tuple has Fixed length (per tuple type)
  • Tuple are Always finite

So for appending new item to a tuple, need to cast it to list, and do append() operation on it, then again cast it back to tuple.

But personally what I felt about the Question is, if Tuples are supposed to be finite, fixed length items and if we are using those data types in our application logics then there should not be a scenario to appending new items OR updating an item value in it. So instead of list of tuples it should be list of list itself, Am I right on this?

Dipak
  • 6,532
  • 8
  • 63
  • 87
  • 1
    There are scenarios where you need to pass a tuple to a function, such as with SQL (psycopg2) or interacting with R (rpy2). The functions don't always work properly if given a list instead of a tuple. Sometimes you also receive a tuple from a function rather than a list. Tuples can guard against mistakenly modifying an original list when you should instead be working on a copy of a list. So yes, either directly or indirectly lists are intermediaries in the answers presented. However, casting back to a tuple at the end is still logical in many scenarios. – Nate Wanner Sep 28 '18 at 20:49
2
    list_of_tuples = [('1', '2', '3', '4'),
                      ('2', '3', '4', '5'),
                      ('3', '4', '5', '6'),
                      ('4', '5', '6', '7')]


    def mod_tuples(list_of_tuples):
        for i in range(0, len(list_of_tuples)):
            addition = ''
            for x in list_of_tuples[i]:
                addition = addition + x
            list_of_tuples[i] = list_of_tuples[i] + (addition,)
        return list_of_tuples

    # check: 
    print mod_tuples(list_of_tuples)
Viktor
  • 259
  • 1
  • 2
  • 7
2

A lot of people is writing tuples are immutables... and that's right! But there is this code:

tuple = ()
for i in range(10):
    tuple += (i,)
print(tuple)

And It works! Why? Well.. that's because in the code there is a "=". Every time you use the operator "=" in Python you assign a new value to an object: you create a new variable!

So you are not modifying the old tuple: you are creating a new one, with the same name (tuple), with value the old one plus something more.

0
OUTPUTS = []
for number in range(len(list_of_tuples))):
    tup_ = list_of_tuples[number]
    list_ = list(tup_)  
    item_ = list_[0] + list_[1] + list_[2] + list_[3]
    list_.append(item_)
    OUTPUTS.append(tuple(list_))

OUTPUTS is what you desire

Questwalker
  • 111
  • 1
  • 5
0

In case of tuple and list, a very simple way can be (suppose) :

tpl = ( 3, 6, 9)
lst = [ 12, 15, 18]
my_tuple = tpl + tuple(lst)
print(my_tuple)
joanis
  • 10,635
  • 14
  • 30
  • 40
0

You could use a generator so that you don't have to alter the underlying list or store a new one. Create it on the fly during your insert so you only loop once.

def my_generator(old_list: list, new_values: tuple):
    for idx, row in enumerate(old_list):
        new_row: list = list(row)

        new_row.append(new_values[idx])

        new_dataset: tuple = tuple(new_row)

        yield new_dataset

def make_sql():
    my_list: list = [
        ('1', '2', '3', '4'),
        ('2', '3', '4', '5'),
        ('3', '4', '5', '6'),
        ('4', '5', '6', '7')
    ]

    my_var: tuple = ('1234', '2345', '3456', '4567')

    my_new_list = my_generator(my_list, my_var)

    'I like SQL Injection attacks!'

    for row in my_new_list:
        print(
            'INSERT INTO users (V1, V2, V3, V4) '
            f'VALUES {row};'
        )


if __name__ == '__main__':
    make_sql()
Jason Callahan
  • 505
  • 5
  • 7