Stack two same-shaped record lists vertically by looping over each batch and appending its rows into a combined list. With pandas, pd.concat([df1, df2]) stacks DataFrames along axis 0 (rows) and ignore_index=True resets the index to a clean 0…n-1 range.

By hand

Loop over batch1 and batch2 separately, appending each record r into combined. Loop over combined a final time to collect names.

naive.py
Replay: real traced execution (multi-file project)
batch1 = [
    {'name': 'al', 'score': 80},
    {'name': 'bo', 'score': 90},
]
batch2 = [
    {'name': 'cy', 'score': 70},
    {'name': 'di', 'score': 85},
]
combined = []
for r in batch1:
    combined.append((r['name'], r['score']))
for r in batch2:
    combined.append((r['name'], r['score']))
names = []
for t in combined:
    names.append(t[0])
print('RESULT:', names)
  1. {'name': 'al', 'score': 80},

    1batch1 = [2    {'name': 'al', 'score': 80},3    {'name': 'bo', 'score': 90},
  2. {'name': 'bo', 'score': 90},

    2    {'name': 'al', 'score': 80},3    {'name': 'bo', 'score': 90},4]
  3. batch1 ← [{'name': 'al', 'score': 80}, {'name': 'bo', 'score': 90}]

    1batch1 = [2    {'name': 'al', 'score': 80},
    values this step[{'name': 'al', 'score': 80}, {'name': 'bo', 'score': 90}]batch1
  4. {'name': 'cy', 'score': 70},

    5batch2 = [6    {'name': 'cy', 'score': 70},7    {'name': 'di', 'score': 85},
  5. {'name': 'di', 'score': 85},

    6    {'name': 'cy', 'score': 70},7    {'name': 'di', 'score': 85},8]
  6. batch2 ← [{'name': 'cy', 'score': 70}, {'name': 'di', 'score': 85}]

    4]5batch2 = [6    {'name': 'cy', 'score': 70},
    values this step[{'name': 'cy', 'score': 70}, {'name': 'di', 'score': 85}]batch2
  7. combined ← []

    8]9combined = []10for r in batch1:
    values this step[]combined
  8. r ← {'name': 'al', 'score': 80}

    9combined = []10for r in batch1:11    combined.append((r['name'], r['score']))
    values this step{'name': 'al', 'score': 80}r
  9. combined ← [('al', 80)]

    10for r in batch1:11    combined.append((r['name'], r['score']))12for r in batch2:
    values this step[] [('al', 80)]combined
  10. r ← {'name': 'bo', 'score': 90}

    9combined = []10for r in batch1:11    combined.append((r['name'], r['score']))
    values this step{'name': 'al', 'score': 80} {'name': 'bo', 'score': 90}r
  11. combined ← [('al', 80), ('bo', 90)]

    10for r in batch1:11    combined.append((r['name'], r['score']))12for r in batch2:
    values this step[('al', 80)] [('al', 80), ('bo', 90)]combined
  12. for r in batch1:

    9combined = []10for r in batch1:11    combined.append((r['name'], r['score']))
  13. r ← {'name': 'cy', 'score': 70}

    11    combined.append((r['name'], r['score']))12for r in batch2:13    combined.append((r['name'], r['score']))
    values this step{'name': 'bo', 'score': 90} {'name': 'cy', 'score': 70}r
  14. combined ← [('al', 80), ('bo', 90), ('cy', 70)]

    12for r in batch2:13    combined.append((r['name'], r['score']))14names = []
    values this step[('al', 80), ('bo', 90)] [('al', 80), ('bo', 90), ('cy', 70)]combined
  15. r ← {'name': 'di', 'score': 85}

    11    combined.append((r['name'], r['score']))12for r in batch2:13    combined.append((r['name'], r['score']))
    values this step{'name': 'cy', 'score': 70} {'name': 'di', 'score': 85}r
  16. combined ← [('al', 80), ('bo', 90), ('cy', 70), ('di', 85)]

    12for r in batch2:13    combined.append((r['name'], r['score']))14names = []
    values this step[('al', 80), ('bo', 90), ('cy', 70)] [('al', 80), ('bo', 90), ('cy', 70), ('di', 85)]combined
  17. for r in batch2:

    11    combined.append((r['name'], r['score']))12for r in batch2:13    combined.append((r['name'], r['score']))
  18. names ← []

    13    combined.append((r['name'], r['score']))14names = []15for t in combined:
    values this step[]names
  19. for t in combined:

    14names = []15for t in combined:16    names.append(t[0])
  20. names ← ['al']

    15for t in combined:16    names.append(t[0])17print('RESULT:', names)
    values this step[] ['al']names
  21. for t in combined:

    14names = []15for t in combined:16    names.append(t[0])
  22. names ← ['al', 'bo']

    15for t in combined:16    names.append(t[0])17print('RESULT:', names)
    values this step['al'] ['al', 'bo']names
  23. for t in combined:

    14names = []15for t in combined:16    names.append(t[0])
  24. names ← ['al', 'bo', 'cy']

    15for t in combined:16    names.append(t[0])17print('RESULT:', names)
    values this step['al', 'bo'] ['al', 'bo', 'cy']names
  25. for t in combined:

    14names = []15for t in combined:16    names.append(t[0])
  26. names ← ['al', 'bo', 'cy', 'di']

    15for t in combined:16    names.append(t[0])17print('RESULT:', names)
    values this step['al', 'bo', 'cy'] ['al', 'bo', 'cy', 'di']names
  27. for t in combined:

    14names = []15for t in combined:16    names.append(t[0])
  28. stdout ← RESULT: ['al', 'bo', 'cy', 'di']

    16    names.append(t[0])17print('RESULT:', names)
    values this stepRESULT: ['al', 'bo', 'cy', 'di']stdout

With pandas

pd.concat([df1, df2], ignore_index=True) stacks the two DataFrames row-by-row. The snapshot shows the merged columns, shape, fresh index, and the combined name column.

library.py
import pandas as pd
from dalib.display import set_display
set_display()

df1 = pd.DataFrame({'name': ['al', 'bo'], 'score': [80, 90]})
df2 = pd.DataFrame({'name': ['cy', 'di'], 'score': [70, 85]})
combined = pd.concat([df1, df2], ignore_index=True)
print('columns:', combined.columns.tolist())
print('shape:', combined.shape)
print('index:', combined.index.tolist())
print('names:', combined['name'].tolist())
print('RESULT:', combined['name'].tolist())
columns: ['name', 'score']
shape: (4, 2)
index: [0, 1, 2, 3]
names: ['al', 'bo', 'cy', 'di']
RESULT: ['al', 'bo', 'cy', 'di']

Implementation notes

  • pd.concat defaults to axis=0 (stack rows). Pass axis=1 to stack columns side-by-side instead.
  • Without ignore_index=True, the result keeps each DataFrame's original index. If both start at 0, the combined index has duplicate labels (0, 1, 0, 1), which can cause unexpected behavior in downstream .loc lookups.
  • pd.concat accepts any list of DataFrames — not just two. Pass a Python list of any length: pd.concat([df1, df2, df3, ...], ignore_index=True).
  • For appending a single new row, pd.concat([df, new_row_df], ignore_index=True) is the modern replacement for the deprecated df.append(row).