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']