nx_prv
nx_prv

Reputation: 127

Iterate through list and replace instance in a certain index?

I have a list called List for the purpose of this question, which contains tuples.

List = [
    ("foo", "bar", 1, 0),
    ("foo", "bar", 3, 1),
    ("foo", "bar", 1, 2)
]

In index position 2 (third item in list) of each sub-list, I need to replace with the corresponding item in another list.

References = ["zero", "one", "two", "three"]

The expected output would be the new List of:

List = [
    ("foo", "bar", "one", 0),
    ("foo", "bar", "three", 1),
    ("foo", "bar", "one", 2)
]

Notice how there are also integers on other parts of the list but these remain unchanged.

My current code replaces all instances of integers which is not what I want:

for r in range(0, len(References)):
    for i in List:
        List[List.index(i)] = [References[t] if x==t else x for x in i]

Q: How would I do this? Thanks in advance.

EDIT: I made a mistake with my code - inside List are tuples, not lists.

Upvotes: 1

Views: 83

Answers (4)

jferard
jferard

Reputation: 8180

First, avoid capititalization of variable names (stick to PEP8 for the naming conventions).

Second, you can use a list comprehension:

>>> L = [
...     ["foo", "bar", 1, 0],
...     ["foo", "bar", 3, 1],
...     ["foo", "bar", 1, 2]
... ]
>>> references = ["zero", "one", "two", "three"]
>>> [row[:2]+[references[row[2]]]+row[3:] for row in L]
[['foo', 'bar', 'one', 0], ['foo', 'bar', 'three', 1], ['foo', 'bar', 'one', 2]]

The original list will not be modified, but a new list will be generated. (Will only work if you have lists, not tuples.)

Third, I guess that one, two, ... is just an example. If you really want number in plain text, instead of hard-coding the references list, you can use some libraries to do the number to word conversion, num2words for instance.

Four, you are performing the equivalent of a SQL JOIN. Current code will fail (raise a KeyError) if the reference is unknwon:

  • for an INNER JOIN, just check if row[2] in references and skip the row if that's not the case.
  • for a LEFT JOIN, replace references[row[2]] by references.get(row[2]) of references.get(row[2], <default value>).

Upvotes: 1

Partho63
Partho63

Reputation: 3117

Tuples are immutable which means you cannot update or change the values of tuple elements. You can follow any one of the following process:

1) You can take portions of existing tuples to create new tuples as the following:

List_One = [
    ("foo", "bar", 1, 0),
    ("foo", "bar", 3, 1),
    ("foo", "bar", 1, 2)
]

List_Two = []

References = ["zero", "one", "two", "three"]

for i in List_One:
    tup = (i[0], i[1], References[i[2]], i[3])
    List_Two.append(tup)

print(List_Two)

2) You can convert tuples to lists, change as you desire, change back the lists to tuples.

List = [
    ("foo", "bar", 1, 0),
    ("foo", "bar", 3, 1),
    ("foo", "bar", 1, 2)
]

References = ["zero", "one", "two", "three"]

for i in range(len(List)):
    List[i] = list(List[i])

for i in List:
    i[2] = References[i[2]]

for i in range(len(List)):
    List[i] = tuple(List[i])

print(List)

Upvotes: 1

Fukiyel
Fukiyel

Reputation: 1166

Do you mean to do this ?

for el in List: el[2] = References[el[2]]

Upvotes: 3

Subbu Gs
Subbu Gs

Reputation: 11

Please use the below code snippet,

List = [
    ["foo", "bar", 1, 0],
    ["foo", "bar", 3, 1],
    ["foo", "bar", 1, 2]
]

References = ["zero", "one", "two", "three"]

for each in List:
    if list(each):
        each[2]=References[each[2]]
print(List)

Note: Reference list position is consdiered as string equvivalent.

Upvotes: 1

Related Questions