惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
O
OpenAI News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
Webroot Blog
Webroot Blog
GbyAI
GbyAI
S
SegmentFault 最新的问题
Cyberwarzone
Cyberwarzone
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
J
Java Code Geeks
Google DeepMind News
Google DeepMind News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 【当耐特】
S
Secure Thoughts
酷 壳 – CoolShell
酷 壳 – CoolShell
AWS News Blog
AWS News Blog
Engineering at Meta
Engineering at Meta
S
Security Affairs
H
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
D
DataBreaches.Net
云风的 BLOG
云风的 BLOG
Hugging Face - Blog
Hugging Face - Blog
Google DeepMind News
Google DeepMind News
Spread Privacy
Spread Privacy
T
Threatpost
Forbes - Security
Forbes - Security
C
Cisco Blogs
Scott Helme
Scott Helme
Attack and Defense Labs
Attack and Defense Labs
Simon Willison's Weblog
Simon Willison's Weblog
腾讯CDC
The Last Watchdog
The Last Watchdog
Cloudbric
Cloudbric
Last Week in AI
Last Week in AI
Recorded Future
Recorded Future
小众软件
小众软件
V
Vulnerabilities – Threatpost
美团技术团队
人人都是产品经理
人人都是产品经理
有赞技术团队
有赞技术团队
Apple Machine Learning Research
Apple Machine Learning Research
Hacker News - Newest:
Hacker News - Newest: "LLM"
I
Intezer
月光博客
月光博客
C
Cyber Attacks, Cyber Crime and Cyber Security
博客园 - 司徒正美
C
Cybersecurity and Infrastructure Security Agency CISA
Martin Fowler
Martin Fowler
博客园 - 聂微东

DigitalOcean Community Tutorials

It's Time to Break Up with Your Cloud: Why AI Teams are Switching We Built a Private-Document AI App to Test Platform Security. Here Is What We Could Actually Verify. PostgreSQL Explained: A Complete Beginner-to-Advanced Guide How To Install and Configure Postfix on Ubuntu How To Build a Web Application Using Flask in Python 3 Build AI Reading List with DigitalOcean Functions and Mistral How To Concatenate Strings in Python How to Allow MySQL Remote Access Securely How To Install and Use Docker on Rocky Linux How To Build a Multi-Agent AI System with Docker Agent DSPy Use Cases: Build Optimized LLM Pipelines How To Submit AJAX Forms with jQuery Build an AI-Powered GPU Fleet Optimizer with the DigitalOcean AI Platform ADK Monitor GPU Utilization in Real Time: A Complete Guide Reduce File Size of Images in Linux - CLI and GUI methods Reduce PDF File Size in Linux: Tools and Methods How To Set Up a Private Docker Registry on Ubuntu How To Troubleshoot Terraform: Errors and Fixes How to Use Go Modules Python Multiprocessing Example: Process, Pool & Queue Convert Class Components to Functional Components with React Hooks How To Install and Configure Ansible on Ubuntu LLM Tokenizers Simplified: BPE, SentencePiece, and More How To Monitor System Authentication Logs on Ubuntu How to Use Traceroute and MTR to Diagnose Network Issues How to Deploy Postgres to Kubernetes Cluster Importing Packages in Go: A Complete Guide Create RAID Arrays with mdadm on Ubuntu How To Make an HTTP Server in Go How To Set Up Time Synchronization on Ubuntu How To Use Struct Tags in Go apt-key Deprecation: Add Repositories with GPG on Ubuntu Linux ps Command: 20 Real-World Examples Python struct.pack and struct.unpack for Binary Data Deadlock in Java: Examples, Detection, and Prevention How To Use Find and Locate to Search for Files on Linux Structured Resume Skill Extraction Using Mistral-7B Inference How to Use the Python Main Function How to Set Up NemoClaw on a DigitalOcean Droplet with 1-Click Build an End-to-End RAG Pipeline for LLM Applications From Single to Multi-Agent Systems: Key Infrastructure Needs Back Up Data to Object Storage Using Restic How to Generate Videos with LTX-2.3 on DigitalOcean GPU Droplets How To Install LAMP Stack (Apache, MySQL, PHP) on Ubuntu How to Download Files with cURL How To Use Variadic Functions in Go Generate UUIDs with uuidgen on Linux How To Use EJS to Template Your Node Application How to Install Node.js on Ubuntu (Step-by-Step Guide) MongoDB Indexes: Improve Query Performance with Node.js LLM Tool Calling with DigitalOcean AI Platform and Databases What are Text Diffusion Models? - An Overview Crafting a Game from Scratch with GPT-5.4 Building Long-Term Memory in AI Agents with LangGraph and Mem0 How To Install PHP 7.4 and Set Up a Local Development Environment on Ubuntu 20.04 Build a GraphQL API in Go to Upload Files to Spaces How To Lint and Format Code with ESLint in Visual Studio Code Train YOLO26 for Retail Object Detection on DigitalOcean GPUs How To Work with JSON in MySQL How to Use the JavaScript .map() Method Building a Scalable App with MongoDB Using DigitalOcean's MCP Server How to Create an SSH Key in Linux: Easy Step-by-Step Guide Measure MySQL Query Performance with mysqlslap How To Use *args and **kwargs in Python 3 Nemotron 3 helped me find the perfect dish rack? A2A vs MCP - How These AI Agent Protocols Actually Differ How To Install and Manage Supervisor Docker Container Images with Watchtower on Ubuntu Getting Started with Qwen3.5 Vision-Language Models How To Create a New Sudo-Enabled User on Ubuntu How to Use Ansible to Install and Set Up Docker on Ubuntu How To Enable Remote Desktop Protocol Using xrdp on Ubuntu 22.04 How To Convert a String to a List in Python How To Check If a String Contains Another String in Python How to Read a Properties File in Python Python Command Line Arguments: sys.argv, argparse, getopt Mastering Grep command in Linux/Unix: A Beginner's Tutorial Understanding Python Data Types How to Implement a Stack in C With Code Examples Python os.system() vs subprocess: Run System Commands How To Install and Use Docker Compose on Ubuntu How to Add and Delete Users on Ubuntu How To Order Query Results in Laravel Eloquent How To Define and Use Handlers in Ansible Playbooks How To Install and Use SQLite on Ubuntu How To Install and Use Homebrew on macOS How To Manage DateTime with Carbon in Laravel and PHP How To Install Git on Ubuntu How To Install and Secure Redis on Ubuntu How To Build and Install Go Programs on Linux Using ldflags to Set Version Information for Go Applications How To Build a Node.js Application with Docker How To Add JavaScript to HTML How To Reset Your MySQL or MariaDB Root Password How To Add Images in Markdown How To Set Up a Production Elasticsearch Cluster with Ansible How To Set Up a Firewall Using firewalld on CentOS Understanding Systemd Units and Unit Files How To Set Up Replication in MySQL How To Use the .htaccess File
Join Python List: Methods, Examples, and Best Practices
Pankaj Kumar · 2026-06-16 · via DigitalOcean Community Tutorials

Introduction

In Python, joining a list means combining its elements into a single string, using a separator to place between each element. The standard tool for this is the string join() method, which takes an iterable (such as a list) and returns one string. This operation is useful whenever you need to turn a list of values into text, for example saving a list of names as a comma-separated line in a file or building a sentence from a list of words.

In this tutorial, you will learn the different ways to join a Python list and combine lists in Python. You will start with the join() method for joining a list of strings, then cover how to join a list of integers and mixed data types, how to handle None values and nested lists, how to concatenate two or more lists with the + operator, list.extend(), the * unpacking operator, and itertools.chain(), and how the methods compare in performance. You will also see why join() lives on the string class rather than the list class, and which modern alternatives Python now offers.

Key Takeaways:

  • The string join() method is the standard and fastest way to join a list of strings into one string with a chosen separator.
  • The syntax is separator.join(iterable): the separator is the string you call join() on, and the list is passed as the argument.
  • join() works only on strings, so joining a list that contains integers, None, or other types raises a TypeError.
  • To join a list of integers, convert each item to a string first with map(str, list) or a list comprehension.
  • To skip None values before joining, use a generator expression such as ",".join(x for x in items if x is not None).
  • Use the + operator or list.extend() to concatenate two lists into a new list, and the * unpacking operator (Python 3.5+) for a concise merge.
  • For joining many or very large lists, itertools.chain() avoids building intermediate lists and uses less memory.
  • Building a string with repeated + in a loop runs in O(n^2) time, while join() runs in O(n); in a benchmark on 100,000 items, join() was about 8 times faster.
  • join() is a string method (not a list method) because it works with any iterable and always returns a string.

Join a Python list of strings with join()

We can use the Python string join() method to join a list of strings. The method is called on the separator string and takes the iterable as its argument, so the general form is separator.join(iterable). Because a list is an iterable, we can pass a list directly. The list should contain only strings; if you try to join a list of integers you will get a TypeError, which the note below explains how to fix.

Let’s look at a short example that joins a list of vowels into a comma-separated string:

vowels = ["a", "e", "i", "o", "u"]
vowels_csv = ",".join(vowels)
print("Vowels are =", vowels_csv)

Output

Vowels are = a,e,i,o,u

The separator can be any string, not just a comma. The next section shows how to join with a space, a newline, or any custom separator.

Join a list with a comma, space, newline, or custom separator

Because the separator is just the string you call join() on, you can change the output format simply by changing that string. A space joins words into a sentence, "\n" puts each item on its own line, and any other string works as a custom separator.

The following example joins the same list three different ways:

words = ["Python", "is", "awesome"]

print(" ".join(words))      # space separator
print("\n".join(words))     # newline separator
print(" -> ".join(words))   # custom separator

Output

Python is awesome
Python
is
awesome
Python -> is -> awesome

The newline join is especially handy when writing a list to a text file, where each element should appear on its own line.

Join an empty list

Joining an empty list is safe and simply returns an empty string, so you do not need a special check for it.

print(repr("".join([])))
print(repr(",".join([])))

Output

''
''

This predictable behavior is convenient when the list might be empty at runtime, since the call will not raise an error.

Join a list of integers in Python

A list of integers cannot be passed to join() directly, because join() only accepts strings. Attempting it raises TypeError: sequence item 0: expected str instance, int found. The fix is to convert each element to a string first, and there are two common ways to do that.

Using map() with join()

The map() function applies str to every element of the list, producing string versions that join() can accept. This is concise and reads well for simple conversions, and you can learn more about it in the tutorial on the Python map() function.

int_list = [1, 2, 3, 4, 5]
joined_str = ",".join(map(str, int_list))
print("Joined string:", joined_str)

Output

Joined string: 1,2,3,4,5

Using a list comprehension for type conversion

A list comprehension does the same conversion and is a good choice when you want to transform each item further, for example formatting numbers while converting them.

int_list = [1, 2, 3, 4, 5]
joined_str = ",".join([str(element) for element in int_list])
print("Joined string:", joined_str)

Output

Joined string: 1,2,3,4,5

Both approaches are correct; map(str, ...) is slightly faster and more compact, while the comprehension is easier to extend when each element needs extra formatting.

Join a list with mixed data types

When a list mixes strings with other types, join() raises a TypeError because it expects every element to already be a string. The list ['Java', 'Python', 1] is a typical example: the integer 1 causes the error.

names = ['Java', 'Python', 1]
single_str = ','.join(names)
print(single_str)

This raises the following error:

Output

TypeError: sequence item 2: expected str instance, int found

The lesson is that a list containing multiple data types cannot be combined into a single string with join() directly; you must convert the non-string items first, as the next two sections show.

Handling None values in a list before joining

A None value triggers the same TypeError, so you need to decide whether to drop the None values or convert them to text. To drop them, filter the list with a generator expression before joining.

items = ["a", None, "b"]
result = ",".join(x for x in items if x is not None)
print(result)

Output

a,b

If you would rather keep a placeholder for the missing value, convert every element with str() instead, which turns None into the text "None".

items = ["a", None, "b"]
result = ",".join(str(x) for x in items)
print(result)

Output

a,None,b

Choose the filtering approach when missing values should disappear, and the conversion approach when their position matters.

Filtering non-string items before joining

The same generator-expression pattern lets you keep only the items you want, for example joining just the string elements of a mixed list and ignoring everything else.

mixed = ['Java', 'Python', 1, None, 'Go']
result = ",".join(x for x in mixed if isinstance(x, str))
print(result)

Output

Java,Python,Go

Using isinstance(x, str) keeps the strings and silently skips the integer and the None, which is useful when a list may contain unpredictable types.

Join a nested list in Python

A nested list (a list of lists) cannot be joined directly either, because its elements are lists rather than strings. You first need to flatten it into a single sequence of strings, and there are two clean ways to do that.

Flattening a nested list with a list comprehension

A nested list comprehension walks each sublist and then each item, producing a flat list of strings that join() can accept.

nested = [["a", "b"], ["c", "d"]]
flat = [item for sub in nested for item in sub]
print(",".join(flat))

Output

a,b,c,d

Using itertools.chain.from_iterable()

For larger nested lists, itertools.chain.from_iterable() flattens the structure lazily without building an intermediate list, which is more memory efficient.

import itertools

nested = [["a", "b"], ["c", "d"]]
print(",".join(itertools.chain.from_iterable(nested)))

Output

a,b,c,d

Both produce the same result; reach for chain.from_iterable() when the nested data is large or streamed, and the comprehension when readability matters most.

What happens when you pass a string to join()

A common point of confusion is calling join() on a single string instead of a list. Because a string is itself an iterable of characters, join() iterates over its individual characters and inserts the separator between each one.

message = "Hello ".join("World")
print(message)

Output

WHello oHello rHello lHello d

As the output shows, this does not produce "Hello World". Because 'World' is a string and strings are iterables of characters, join() inserts 'Hello ' between every individual character of 'World', not between two whole words. To combine two whole strings, use concatenation with + or an f-string instead of join().

Why join() is a string method and not a list method

A question many Python developers ask is why join() belongs to the string class and not to the list class. Wouldn’t the syntax below be easier to remember?

vowels_csv = vowels.join(",")

There is a well-known StackOverflow discussion about this. The core reasoning is that join() works with any iterable, not just lists, and it always returns a string. If join() were a method on every iterable, the same logic would have to be duplicated across lists, tuples, sets, generators, and more. Placing it on the string class instead means a single implementation handles every iterable, and the separator is naturally the string you call the method on.

The official Python documentation describes str.join() as follows: “Return a string which is the concatenation of the strings in iterable.” It also notes that “a TypeError will be raised if there are any non-string values in iterable, including bytes objects.” This is exactly the behavior you saw in the integer and mixed-type examples above, and it confirms why the method is defined where it is.

Concatenate two or more lists in Python

Joining for string output is different from concatenating lists into a new list. When your goal is a combined list rather than a string, Python gives you several options, each with different performance characteristics. You can read more in the tutorial on concatenating lists in Python.

Using the + operator

The + operator creates a new list by joining two existing lists, which is the simplest approach for a simple merge of small lists.

list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined = list1 + list2
print(combined)

Output

[1, 2, 3, 4, 5, 6]

Using list.extend()

The list.extend() method adds every element of one list onto another in place, without creating a new list. It is the right choice when you are growing an existing list, and it is covered alongside other list-growing methods in the tutorial on adding elements to a list in Python.

combined = [1, 2, 3]
combined.extend([4, 5, 6])
print(combined)

Output

[1, 2, 3, 4, 5, 6]

Using the * unpacking operator (Python 3.5+)

Since Python 3.5, the * unpacking operator can be used inside list literals to spread several lists into a new list. It is concise and works with more than two lists at once.

list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined = [*list1, *list2]
print(combined)

Output

[1, 2, 3, 4, 5, 6]

Using itertools.chain() for memory-efficient joins

For merging many lists, or very large ones, itertools.chain() returns an iterator that yields elements from each list in turn without building intermediate lists, which keeps memory usage low.

import itertools

list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined = list(itertools.chain(list1, list2))
print(combined)

Output

[1, 2, 3, 4, 5, 6]

Joining two lists without duplicates

If you need a combined list with duplicate values removed while preserving order, concatenate the lists and pass the result to dict.fromkeys(), which keeps only the first occurrence of each value.

list1 = [1, 2, 3]
list2 = [3, 4, 5]
combined = list(dict.fromkeys(list1 + list2))
print(combined)

Output

[1, 2, 3, 4, 5]

Using dict.fromkeys() preserves insertion order (guaranteed since Python 3.7), which a plain set() would not.

Split a string back into a list with split()

The split() method is the inverse of joining: it breaks a string into a list using a delimiter. This is useful when you have joined a list into a string and later need the original list back.

names = ['Java', 'Python', 'Go']
delimiter = ','
single_str = delimiter.join(names)
print('String:', single_str)

split = single_str.split(delimiter)
print('List:', split)

Output

String: Java,Python,Go
List: ['Java', 'Python', 'Go']

Using the same delimiter to split the string returns the original list, so join() and split() round-trip cleanly.

Splitting only n times

The split() method takes an optional second argument that limits how many splits are performed, which is handy when only the first few fields matter.

names = ['Java', 'Python', 'Go']
delimiter = ','
single_str = delimiter.join(names)

split = single_str.split(delimiter, 1)
print('List:', split)

Output

List: ['Java', 'Python,Go']

Because the split count was set to 1, the operation ran only once and left the remaining delimiter in place.

Performance comparison: which join method is fastest?

When combining strings or lists, the method you choose has real performance implications, especially as the data grows. The key idea is time complexity: join() and extend() run in linear O(n) time, while repeatedly using + in a loop runs in quadratic O(n^2) time because each + creates a brand-new object and copies all the existing elements again.

Benchmark results for small vs. large lists

To make this concrete, the following benchmark builds a string of 100,000 items two ways, using join() and using += in a loop, and times each with the timeit module.

import timeit

words = [str(i) for i in range(100_000)]

def with_join():
    return ",".join(words)

def with_plus_loop():
    s = ""
    for w in words:
        s += w + ","
    return s

print(f"join : {timeit.timeit(with_join, number=20) / 20 * 1000:.2f} ms")
print(f"+=   : {timeit.timeit(with_plus_loop, number=20) / 20 * 1000:.2f} ms")

On one test machine running Python 3.14, this produced the following output (your exact numbers will vary by hardware):

Output

join : 1.48 ms
+=   : 12.61 ms

In this run, join() was about 8 times faster than building the string with +=. The gap widens as the list grows, which is the practical consequence of the O(n) versus O(n^2) difference. The same pattern holds for lists: concatenating 1,000 lists of 1,000 integers each with repeated out = out + lst took roughly 540 ms in our testing, while list.extend() took about 1 ms and itertools.chain() about 3 ms, since the repeated + rebuilds and copies the growing list on every step.

Time and space complexity by method

The table below summarizes the complexity and memory behavior of each method so you can choose based on the size and shape of your data.

Method Time Complexity Creates Intermediate Copies? Best For
str.join() O(n) No (single pass) Joining a list of strings into one string
+ in a loop O(n²) Yes (new object each step) Avoid for large data; fine for a single small merge
list.extend() O(n) No (in place) Growing an existing list
itertools.chain() O(n) No (lazy iterator) Merging many or very large lists

Choose the method that fits your use case: join() for strings, extend() or chain() for lists, and reserve a single + for small, one-off merges.

Method comparison table

Beyond raw performance, the methods differ in what they are for, how readable they are, and which Python versions support them. The table below compares the main options at a glance.

Method Use case Output Readability Python version
str.join() Join a list of strings into one string str High All 3.x
+ operator Concatenate two lists or two strings new list / str High All 3.x
list.extend() Add items to an existing list in place modifies list High All 3.x
* unpacking Merge several lists into a new list new list Medium 3.5+
itertools.chain() Iterate over many lists without copying iterator Medium All 3.x
dict | operator Merge two dictionaries new dict High 3.9+

Modern alternatives: unpacking and the | operator

Recent Python versions added cleaner syntax for merging collections. The * unpacking operator, shown earlier, is the idiomatic modern way to merge lists into a new list. For dictionaries, PEP 584 introduced the | merge operator in Python 3.9, giving dictionaries the same kind of concise merge syntax that + gives lists.

defaults = {"theme": "light", "lang": "en"}
overrides = {"lang": "fr"}
settings = defaults | overrides
print(settings)

Output

{'theme': 'light', 'lang': 'fr'}

When the same key appears in both dictionaries, the value from the right-hand dictionary wins, which is why lang becomes "fr". There is also an in-place version, |=, which updates the left dictionary instead of creating a new one.

Some practical use cases

These methods map naturally onto everyday tasks, so it helps to see when each one shines.

  • The first common case is using join() for strings: when you have a list of strings and need a single delimited string, join() is the preferred method. This is useful for building a sentence from a list of words or combining names with commas, as shown throughout this tutorial.

  • The second common case is combining lists with itertools.chain(): for merging multiple lists, especially large ones, itertools.chain() offers a memory-efficient solution because it avoids creating intermediate lists. This matters when working with large datasets or when you need to process elements from several lists in a single iteration. You can read more in the tutorial on concatenating lists in Python.

Combining lists with dictionaries or sets

Lists, dictionaries, and sets behave differently, so combining them requires a little care. Lists are ordered sequences, dictionaries are collections of key-value pairs (ordered by insertion since Python 3.7), and sets are unordered collections of unique elements. The examples below show how to merge a list with each of the other two.

To combine a list with a dictionary, extract the dictionary’s keys or values and concatenate them with the list. This is useful when merging data from different sources.

my_list = [1, 2, 3]
my_dict = {'a': 4, 'b': 5}

combined_keys = my_list + list(my_dict.keys())
print(combined_keys)

combined_values = my_list + list(my_dict.values())
print(combined_values)

Output

[1, 2, 3, 'a', 'b']
[1, 2, 3, 4, 5]

In the code above, list() converts the dictionary’s keys or values into a list, which is then concatenated with my_list using the + operator.

To combine a list with a set, convert the set to a list first, since sets are unordered and cannot be concatenated to a list directly.

my_list = [1, 2, 3]
my_set = {4, 5, 6}

combined = my_list + list(my_set)
print(combined)

Output

[1, 2, 3, 4, 5, 6]

Here list() turns the set into a list before concatenation. Note that the order of elements coming from the set is not guaranteed, because sets are unordered.

FAQs

1. How to join a list of strings in Python?

To join a list of strings into a single string, call the join() method on a separator and pass the list as the argument, using the form separator.join(list). The separator can be any string, such as a comma or a space.

words = ['Hello', 'World']
sentence = ' '.join(words)
print(sentence)

This prints Hello World. If the list contains non-string items, convert them first with map(str, list).

2. How can I join two lists in Python?

To combine two lists into one new list, use the + operator for a quick merge, or itertools.chain() for better performance with large lists. Use list.extend() if you want to grow an existing list in place rather than create a new one.

list1 = [1, 2]
list2 = [3, 4]
combined = list1 + list2
print(combined)

This prints [1, 2, 3, 4].

3. What does join() do in Python?

The join() method concatenates the strings in an iterable into a single string, separated by the string you call it on. It works on any iterable of strings (lists, tuples, generators) and always returns a string, which is why it is a method of str rather than list.

4. What does strip() do in Python?

The strip() method removes leading and trailing whitespace (or other specified characters) from a string and returns the cleaned string. It is often used to tidy up individual items before or after joining them, for example removing stray spaces parsed from a file.

5. What is the correct syntax for str.join() in Python?

The correct syntax is separator.join(iterable), where the separator is the string placed between elements and iterable is the list (or other iterable) of strings to join. A frequent mistake is writing list.join(separator), which does not exist and raises an AttributeError.

print("-".join(["2026", "06", "09"]))

This prints 2026-06-09, showing the separator placed between each element.

6. How do you join a Python list of integers into a single string?

Convert each integer to a string first, because join() accepts only strings. The simplest way is ",".join(map(str, numbers)), which applies str to every element before joining.

numbers = [1, 2, 3]
print(",".join(map(str, numbers)))

This prints 1,2,3. Joining the integers directly would raise TypeError: sequence item 0: expected str instance, int found.

7. How do you join two separate lists into one list in Python?

To produce a combined list (not a string), use the + operator, the * unpacking operator, list.extend(), or itertools.chain(). This is different from join(), which always returns a string rather than a list.

a = [1, 2]
b = [3, 4]
print([*a, *b])

This prints [1, 2, 3, 4].

8. What is the difference between join() and concatenation using + in Python?

The join() method is built for combining many strings efficiently in a single pass (O(n)), while + creates a new object every time it runs. Using + once on two small values is fine, but using + repeatedly in a loop is O(n^2) and slow, so join() is preferred for combining a list of strings.

9. How do you join a list with a newline character in Python?

Use "\n" as the separator, so each list element appears on its own line. This is the standard way to prepare a list for writing to a text file.

lines = ["first", "second", "third"]
print("\n".join(lines))

This prints each word on a separate line.

10. Can you join a list that contains None values?

Not directly, because a None value raises TypeError: sequence item N: expected str instance, NoneType found. Filter the None values out with a generator expression, or convert every element with str() if you want a placeholder.

items = ["a", None, "b"]
print(",".join(x for x in items if x is not None))

This prints a,b.

11. When should you use itertools.chain() instead of the + operator?

Use itertools.chain() when merging many lists or very large ones, because it returns a lazy iterator and avoids building intermediate lists, keeping memory usage low. The + operator is fine for a single merge of small lists, but chaining many + operations copies the growing result repeatedly and becomes slow.

12. Why does Python use str.join(list) instead of list.join(str)?

Because join() works with any iterable and always returns a string, it makes sense to define it once on the string class rather than duplicate it across every iterable type. The separator is naturally the string you call the method on, which is why the design is separator.join(iterable).

Conclusion

In this tutorial, you learned the various ways to join and combine lists in Python. You joined a list of strings with the join() method and customized the separator, handled lists of integers, mixed types, None values, and nested lists, and concatenated lists using the + operator, list.extend(), the * unpacking operator, and itertools.chain(). You also compared the methods by performance and complexity, saw why join() is a string method, and explored modern alternatives like the dictionary | operator in Python 3.9+.

To further enhance your knowledge of Python programming, we recommend checking out the following tutorials:

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.