Home > other >  How can I combine lists within a list into a single list?
How can I combine lists within a list into a single list?

Time:06-03

When I pull data from my model, data comes in lists. I want to display this incoming data as a single list. I tried a few things for this, but it comes up in different indexes.

class Tickets():
    
    def __init__(self,username):
        self.username = username
        
    def getTicketList(self):
        ticketList = []
        userTicketModel = CekilisModel.objects.filter(username=self.username)
        userCount = userTicketModel.count()
        if(userCount > 0):
            while userCount > 0:
                userCount -= 1
                ticketList.append(userTicketModel[userCount].tickets) 
            ticketList.extend(ticketList)
            print(ticketList)
        return(userTicketModel)
    

Output:

["['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']", "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']", "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']", 'Y666KCF', "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']", "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']", "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']", 'Y666KCF']

What I Want Example Output:

['J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR']

CodePudding user response:

Probably the easiest way to parse those string lists into actual lists is to use eval(), although I am not sure if its the best approach. Here is the code that does what you want using eval():

from functools import reduce

# this assumes your individual strings are all of length 7 like in example
# `l` is the name of the list containing your `output`
l = [eval(x) if len(x) > 7 else [x] for x in l]
# then flatten the array using functools.reduce
l = reduce(lambda x, y: x y, l)

Also note, I am not sure what is the purpose of your code and where the output is coming from. If its from some invalidated user input, using eval() would be a huge security issue, as it essentially executes the code that is passed to it as a string.

CodePudding user response:

as @Arch113 said, eval is a good way:

o=["['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']", "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']", "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']", 'Y666KCF', "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']", "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']", "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']", 'Y666KCF']
l = [eval(x) if len(x) > 7 else [x] for x in o]
print(sum(l, []))
#output
['J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'Y666KCF', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'Y666KCF']

CodePudding user response:

The sound way would be to write a parser that would translate the individual data responses into actual lists. Since the strings look to be mostly Json-compatible, I'd run a Json parser over them. Just replace the ' with ". E.g.:

import json

def _parse_tickets_response(tickets: str) -> List[str]:
    return json.loads(tickets.replace("'", '"'))

class Tickets():
    def __init__(self, username):
        self.username = username
        
    def getTicketList(self):
        ticketList = []
        userTicketModel = CekilisModel.objects.filter(username=self.username)
        userCount = userTicketModel.count()
        if userCount > 0:
            while userCount > 0:
                userCount -= 1
                ticketList.extend(
                    _parse_tickets_response(
                        userTicketModel[userCount].tickets
                    )
                )
            print(ticketList)
        return(userTicketModel)

Btw, Python uses lower snake case.

CodePudding user response:

Please don't suggest eval. Not even to say it's a risk. Especially not when you have ast.literal_eval to use instead.

Just don't.

# this was formatted through `black`, mostly for the list comprehension bit
from ast import literal_eval

input_ = [
    "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']",
    "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']",
    "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']",
    "Y666KCF",
    "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']",
    "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']",
    "['J2V6UEQ', 'OOKXWXY', 'VXC7FGR']",
    "Y666KCF",
]


output_ = []
for v in input_:
    if v.startswith("[") and v.endswith("]"):
        v = literal_eval(v)
    else:
        v = [v]
    output_.extend(v)

print(output_)

# partially using a list comprehension, which can be faster
# the formatting isn't necessary, you could have it all on one line instead.
output_ = []
[
    output_.extend(v2)
    for v in input_
    if (v2 := literal_eval(v) if v.startswith("[") and v.endswith("]") else [v])
]

print(output_)

#cribbing the sum function from Talha's answer to make it more functional
output_ = sum(
    [
        literal_eval(v) if v.startswith("[") and v.endswith("]") else [v]
        for v in input_
    ],
    [],
)

print(output_)

output:

['J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'Y666KCF', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'Y666KCF']
['J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'Y666KCF', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'J2V6UEQ', 'OOKXWXY', 'VXC7FGR', 'Y666KCF']

  • Related