Pax
Given a list of items:

python
>>> givenList = [1, 2, 3]


I would like to convert the list to a list of tuples; where each tuple is a duplicate of every item in the list:

python
>>> givenListOfTuples = [(1,1), (2,2), (3,3)]


## Current Solution

python
givenList = [1, 2, 3]
givenListOfTuples = [(item, item) for item in givenList]


Given that item is repeated multiple times, intuition tells me that this may not be the most pythonic way to do this.

Is there an alternative solution?
wizzwizz4
I think you've probably found the most Pythonic solution already, but it depends on the context. In certain scenarios, this might be better:

python
given_list = [1, 2, 3]
given_list_of_tuples = [(item,)*2 for item in given_list]


This has a slightly different _meaning_, even though it does the same thing. If it didn't occur to you, though, you probably don't want it; I can't think of a place I'd use it.

Your solution satisfies many of the lines of the Zen of Python:

> python
> >>> import this
> 
>
> ## The Zen of Python, by Tim Peters
> Beautiful is better than ugly.
> **Explicit is better than implicit.**
> **Simple is better than complex.**
> Complex is better than complicated.
> **Flat is better than nested.**
> **Sparse is better than dense.**
> Special cases aren't special enough to break the rules.
> **Although practicality beats purity.**
> Errors should never pass silently.
> Unless explicitly silenced.
> In the face of ambiguity, refuse the temptation to guess.
> **There should be one-- and preferably only one --obvious way to do it.**
> Although that way may not be obvious at first unless you're Dutch.
> Now is better than never.
> Although never is often better than *right* now.
> If the implementation is hard to explain, it's a bad idea.
> **If the implementation is easy to explain, it may be a good idea.**
> Namespaces are one honking great idea -- let's do more of those!

If you look at the dissassembly, your solution is also close to optimal:

python
>>> import dis
>>> dis.dis("[(item, item) for item in givenList]")
Disassembly of <code object <listcomp> at 0x7f66e13455d0, file "<dis>", line 1>:
1           0 BUILD_LIST               0
>>    4 FOR_ITER                12 (to 18)
6 STORE_FAST               1 (item)
12 BUILD_TUPLE              2
14 LIST_APPEND              2
16 JUMP_ABSOLUTE            4
>>   18 RETURN_VALUE


Compare with my solution:

python
>>> dis.dis("[(item,)*2 for item in given_list]")
Disassembly of <code object <listcomp> at 0x7f66e13455d0, file "<dis>", line 1>:
1           0 BUILD_LIST               0
>>    4 FOR_ITER                14 (to 20)
6 STORE_FAST               1 (item)
10 BUILD_TUPLE              1
14 BINARY_MULTIPLY
16 LIST_APPEND              2
18 JUMP_ABSOLUTE            4
>>   20 RETURN_VALUE


And the (near) optimal:

python
>>> dis.dis(hand_crafted_bytecode)
Dissassembly of <code object <listcomp> at 0x7f66e390f3a0, file "tapythonq1514.py", line 8>:
8           0 BUILD_LIST               0
10     >>    4 FOR_ITER                 8 (to 14)
11           6 DUP_TOP
12           8 BUILD_TUPLE              2
13          10 LIST_APPEND              2
14          12 JUMP_ABSOLUTE            4
15     >>   14 RETURN_VALUE


A peephole optimiser would be able to transform your solution into this near-optimal bytecode, but not my solution. I think what you've got already is hard to beat.