【问题标题】:Combine multiple tuples into a list of tuples将多个元组组合成一个元组列表
【发布时间】:2022-06-15 07:52:48
【问题描述】:

我有一系列元组,这些元组是通过循环 SQL 查询的结果及其参数输出的。到目前为止,我有:

  Answers = ((userId, p[0], questions, i[0]) for i in strQueryTemplateForAnswerColumn)
            AnswerList = []
            for i in Answers:
                AnswerList.append(i)
                print(AnswerList)

导致:

[(42, 1, 1, 3)]
[(296, 1, 1, 5)]
[(1358, 1, 1, -1)].....etc for a few thousand rows.

我要做的是将这些元组组合成一个元组列表,而不是将每个元组转换为一个列表。如:

[(42, 1, 1, 3), (296, 1, 1, 5), (1358, 1, 1, -1)]

这是为了最终将其转换为具有 4 列/标题的 pandas df。

这里是完整的代码供参考:

cursor = conn.cursor()
allSurveyID = cursor.execute("""SELECT SurveyId FROM dbo.[Survey]""").fetchall()

for a in allSurveyID:
p = a
currentSurveyIDs = cursor.execute("""
DECLARE @SurveyID INT = ?
                SELECT *
           FROM
           (
              SELECT
                 SurveyId,
                 QuestionId,
                 1 as InSurvey
              FROM
                 SurveyStructure
              WHERE
                 SurveyId = @SurveyID
              UNION
              SELECT 
                 @SurveyID as SurveyId,
                 Q.QuestionId,
                 0 as InSurvey
              FROM
                 Question as Q
              WHERE NOT EXISTS
              (
                 SELECT *
                 FROM SurveyStructure as S
                 WHERE S.SurveyId = @SurveyID AND S.QuestionId = Q.QuestionId
              )
           ) as t
           ORDER BY QuestionId
            """, p).fetchall()

    for b in currentSurveyIDs:
        survey = (b[0])
        questions = (b[1])
        InSurvey = (b[2])

        allUserID = cursor.execute("""SELECT UserId FROM dbo.[Answer] ORDER BY 
UserId""").fetchall()

        for i in allUserID:
            userId = i[0]

            if InSurvey == 1:
                strQueryTemplateForAnswerColumn = cursor.execute("""SELECT COALESCE 
                                  ((SELECT 
                                   a.Answer_Value
                                   FROM dbo.Answer a 
                                   WHERE a.UserId = ?
                                   AND a.SurveyId = ?
                                   AND a.QuestionId = ?
                                   ),-1) AS ANS_Q?""", userId, survey, questions, questions).fetchall()

                    Answers = ((userId, p[0], questions, i[0]) for i in 
                                        strQueryTemplateForAnswerColumn)
                    AnswerList = []
                    for i in Answers:
                       AnswerList.append(i)
                       print(AnswerList)

感谢您的意见

【问题讨论】:

  • 您是否在寻找extend() 的功能而不是append()

标签: python sql list


【解决方案1】:

我认为您是在说您有一个类似 [(42, 1, 1, 3)] 的列表,并且您想将其转换为类似 (42, 1, 1, 3) 的列表。

你可以这样做:

listOfListOfTuples = [
    [(42, 1, 1, 3)],
    [(296, 1, 1, 5)],
    [(1358, 1, 1, -1)]
]

print(listOfListOfTuples)

listOfTuples = [x[0] for x in listOfListOfTuples]
print(listOfTuples)

输入:

[[(42, 1, 1, 3)], [(296, 1, 1, 5)], [(1358, 1, 1, -1)]]

输出:

[(42, 1, 1, 3), (296, 1, 1, 5), (1358, 1, 1, -1)]

【讨论】:

  • 感谢您的评论。然而,这并不完全是我所追求的:我的输入是 [(42, 1, 1, 3)] [(296, 1, 1, 5)] [(1358, 1, 1, -1)] 在那里没有逗号分隔每个对象。将每一行(例如 (42,1,1,3))附加到列表中会导致包含每个对象的一千个列表,而不是所有一千个元组的一个列表。我有点不知道该怎么做。
  • 我不确定我是否完全理解您要执行的操作,但也许您只需将语句 AnswerList = [] 移到外部循环之一开始之前:for i in allUserID:for b in currentSurveyIDs:for a in allSurveyID:。作为一个小评论,我至少会取消缩进 print(AnswerList) 行,因此它不再位于循环 for i in Answers: 内。
  • 我发现更改缩进会导​​致打印的行数减少。在每个打印输出通过附加而不是一个逗号分隔元组列表转换为列表的情况下,问题仍然存在。当我打印数据类型时,我得到: * 10000。相反,我想要一个包含一千个元组的列表。
  • 复习。您有几个嵌套循环:for afor bfor i 和另一个 for i(考虑将内部 for i 更改为 for answer)。在for b 中,您使用推导将Answers 初始化为元组生成器(考虑将推导中的for i 更改为例如for v 以避免名称混淆)。在for i in Answers 循环中,您有效地将生成器中的元组复制到列表AnswerList 中。这应该完全符合您的要求,除了您在 for i in Answers 循环之前将 AnswerList 重置为空。尝试将AnswerList = [] 移到所有循环之外?
【解决方案2】:

感谢您的 cmets。这行得通。

AnswerCol = []
AnswerColNull = []

# Loop through Survey and retrieve SurveyIDs while executing query to return the SurveyIDs, QuestionIDs and whether
# the question is in the survey

for a in allSurveyID:
    p = a[0]
    currentSurveyIDs = cursor.execute("""

                    SELECT *
               FROM
               (
                  SELECT
                     SurveyId,
                     QuestionId,
                     1 as InSurvey
                  FROM
                     SurveyStructure
                  WHERE
                     SurveyId = ?
                  UNION
                  SELECT 
                     ? as SurveyId,
                     Q.QuestionId,
                     0 as InSurvey
                  FROM
                     Question as Q
                  WHERE NOT EXISTS
                  (
                     SELECT *
                     FROM SurveyStructure as S
                     WHERE S.SurveyId = ? AND S.QuestionId = Q.QuestionId
                  )
               ) as t
               ORDER BY QuestionId
                """, p, p, p).fetchall()

    # Assign columns from above query to variables
    for b in currentSurveyIDs:
        survey = (b[0])
        questions = (b[1])
        InSurvey = (b[2])

        # Get all UserIDs and assign to variable
        allUserID = cursor.execute("""SELECT UserId FROM dbo.[Answer] ORDER BY UserId""").fetchall()
        for c in allUserID:
            userId = c[0]

            # If the question is in the survey, proceed with the AnswerColumn template query
            if InSurvey == 1:

                strQueryTemplateForAnswerColumn = cursor.execute("""SELECT COALESCE 
                                      ((SELECT 
                                       a.Answer_Value
                                       FROM dbo.Answer a 
                                       WHERE a.UserId = ?
                                       AND a.SurveyId = ?
                                       AND a.QuestionId = ?
                                       ),-1) AS ANS_Q?""", userId, survey, questions, questions).fetchall()

                # Generate rows for the table by appending each value to a list, creating a row then appending
                # the rows to a list outside the for loop
                Answer_List = []
                for d in strQueryTemplateForAnswerColumn:
                    Answer_parts = userId, p, questions, d[0]
                    Answer_List.append(Answer_parts)
                AnswerColNull.append(Answer_List)

            # Same procedure for the NULL values: if the question is not in the survey, use NULL answer template
            # query
            elif InSurvey == 0:
                strQueryTemplateForNullColumnn = cursor.execute(""" SELECT NULL AS ANS_?""",
                                                                questions).fetchall()
                # Generate rows for the table by appending each value to a list, creating a row then appending
                # the rows to a list outside the for loop
                Answer_ListNull = []
                for e in strQueryTemplateForNullColumnn:
                    Answer_partsNull = userId, p, questions, e[0]
                    Answer_ListNull.append(Answer_partsNull)
                AnswerColNull.append(Answer_ListNull)

# Append the values only of each list, cast to a tuple then appended to another list
AnswerColValsNull = []
for f in AnswerColNull:
    AnswerColValsNull.append(tuple(f[0]))

AnswerColVals = []
for g in AnswerCol:
    AnswerColVals.append(tuple(g[0]))

# Combine the list containing UserID, SurveyID, QuestionID, and Answer_Value
# At this point all the information is in a list of tuples
final = AnswerColVals + AnswerColValsNull

【讨论】:

    猜你喜欢
    • 2022-08-18
    • 2015-10-30
    • 2018-10-05
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-23
    相关资源
    最近更新 更多