Repository: Qiskit/qiskit

Issue:
Initial layout does not support some types of list
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**: master
- **Python version**:
- **Operating system**:

### What is the current behavior?
This fails:

```python
lay = QuantumCircuit(5, 5)

lay.h(2)
lay.cx(2, 1)
lay.cx(1, 0)
lay.cx(2, 3)
lay.cx(3, 4)
lay.barrier()
lay.measure(range(5), range(5))

layout = list(np.random.permutation(5))
job6 = execute(lay, backend, initial_layout=layout)
```

with error:
`
AttributeError: 'list' object has no attribute 'get_physical_bits'`

but inputting the resulting list by hand works.


### Steps to reproduce the problem



### What is the expected behavior?



### Suggested solutions





Discussion:

Resolving patch:
diff --git a/qiskit/compiler/transpile.py b/qiskit/compiler/transpile.py
--- a/qiskit/compiler/transpile.py
+++ b/qiskit/compiler/transpile.py
@@ -24,6 +24,7 @@
 from qiskit.circuit.quantumregister import Qubit
 from qiskit import user_config
 from qiskit.transpiler.exceptions import TranspilerError
+from qiskit.converters import isinstanceint, isinstancelist
 
 
 def transpile(circuits,
@@ -330,13 +331,17 @@ def _parse_initial_layout(initial_layout, circuits):
     # initial_layout could be None, or a list of ints, e.g. [0, 5, 14]
     # or a list of tuples/None e.g. [qr[0], None, qr[1]] or a dict e.g. {qr[0]: 0}
     def _layout_from_raw(initial_layout, circuit):
-        if isinstance(initial_layout, list):
-            if all(isinstance(elem, int) for elem in initial_layout):
+        if initial_layout is None or isinstance(initial_layout, Layout):
+            return initial_layout
+        elif isinstancelist(initial_layout):
+            if all(isinstanceint(elem) for elem in initial_layout):
                 initial_layout = Layout.from_intlist(initial_layout, *circuit.qregs)
             elif all(elem is None or isinstance(elem, Qubit) for elem in initial_layout):
                 initial_layout = Layout.from_qubit_list(initial_layout)
         elif isinstance(initial_layout, dict):
             initial_layout = Layout(initial_layout)
+        else:
+            raise TranspilerError("The initial_layout parameter could not be parsed")
         return initial_layout
 
     # multiple layouts?
diff --git a/qiskit/converters/__init__.py b/qiskit/converters/__init__.py
--- a/qiskit/converters/__init__.py
+++ b/qiskit/converters/__init__.py
@@ -21,3 +21,25 @@
 from .dag_to_circuit import dag_to_circuit
 from .ast_to_dag import ast_to_dag
 from .circuit_to_instruction import circuit_to_instruction
+
+
+def isinstanceint(obj):
+    """ Like isinstance(obj,int), but with casting. Except for strings."""
+    if isinstance(obj, str):
+        return False
+    try:
+        int(obj)
+        return True
+    except TypeError:
+        return False
+
+
+def isinstancelist(obj):
+    """ Like isinstance(obj, list), but with casting. Except for strings and dicts."""
+    if isinstance(obj, (str, dict)):
+        return False
+    try:
+        list(obj)
+        return True
+    except TypeError:
+        return False
diff --git a/qiskit/transpiler/layout.py b/qiskit/transpiler/layout.py
--- a/qiskit/transpiler/layout.py
+++ b/qiskit/transpiler/layout.py
@@ -23,6 +23,7 @@
 
 from qiskit.circuit.quantumregister import Qubit
 from qiskit.transpiler.exceptions import LayoutError
+from qiskit.converters import isinstanceint
 
 
 class Layout():
@@ -87,11 +88,11 @@ def from_dict(self, input_dict):
     @staticmethod
     def order_based_on_type(value1, value2):
         """decides which one is physical/virtual based on the type. Returns (virtual, physical)"""
-        if isinstance(value1, int) and isinstance(value2, (Qubit, type(None))):
-            physical = value1
+        if isinstanceint(value1) and isinstance(value2, (Qubit, type(None))):
+            physical = int(value1)
             virtual = value2
-        elif isinstance(value2, int) and isinstance(value1, (Qubit, type(None))):
-            physical = value2
+        elif isinstanceint(value2) and isinstance(value1, (Qubit, type(None))):
+            physical = int(value2)
             virtual = value1
         else:
             raise LayoutError('The map (%s -> %s) has to be a (Bit -> integer)'
@@ -272,7 +273,7 @@ def from_intlist(int_list, *qregs):
         Raises:
             LayoutError: Invalid input layout.
         """
-        if not all(isinstance(i, int) for i in int_list):
+        if not all(isinstanceint(i) for i in int_list):
             raise LayoutError('Expected a list of ints')
         if len(int_list) != len(set(int_list)):
             raise LayoutError('Duplicate values not permitted; Layout is bijective.')


Test patch:
diff --git a/test/python/transpiler/test_layout.py b/test/python/transpiler/test_layout.py
--- a/test/python/transpiler/test_layout.py
+++ b/test/python/transpiler/test_layout.py
@@ -17,6 +17,7 @@
 import copy
 import unittest
 import warnings
+import numpy
 
 from qiskit.circuit import QuantumRegister, Qubit
 from qiskit.transpiler.layout import Layout
@@ -325,6 +326,19 @@ def test_layout_from_intlist(self):
         self.assertDictEqual(layout._p2v, expected._p2v)
         self.assertDictEqual(layout._v2p, expected._v2p)
 
+    def test_layout_from_intlist_numpy(self):
+        """Create a layout from a list of numpy integers. See #3097
+        """
+        qr1 = QuantumRegister(1, 'qr1')
+        qr2 = QuantumRegister(2, 'qr2')
+        qr3 = QuantumRegister(3, 'qr3')
+        intlist_layout = numpy.array([0, 1, 2, 3, 4, 5])
+        layout = Layout.from_intlist(intlist_layout, qr1, qr2, qr3)
+
+        expected = Layout.generate_trivial_layout(qr1, qr2, qr3)
+        self.assertDictEqual(layout._p2v, expected._p2v)
+        self.assertDictEqual(layout._v2p, expected._v2p)
+
     def test_layout_from_intlist_short(self):
         """If the intlist is longer that your quantum register, map them to None.
         virtual  physical