# Printing key:value pairs from pyDataset?

**URL:** <https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415>\
**Category:** Ignition\
**Tags:** perspective\
**Created:** [July 14, 2023, 9:07pm UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415 "2023-07-14T21:07:39Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![ian.sebryk](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ian.sebryk/32/49319_2.png) [@ian.sebryk](https://forum.inductiveautomation.com/u/ian.sebryk)\
**Post date:** [July 14, 2023, 9:07pm UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415/1 "2023-07-14T21:07:39Z")

</div>

```python
# data passed in from user dataset and converted with system.dataset.toPyDataSet()
for row in pyDataset:
    for key, value in row:
        message = 'key: ' + key + ', value: ' + value
        system.perspective.print(message)

```

doesn't work. `Error_Configuration`. this is a JSON object! where's the error!?!?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 14, 2023, 9:16pm UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415/2 "2023-07-14T21:16:21Z")

</div>

A PyDataset contains PyRows. PyRows are list-like objects, not dictionary-like objects. So you can't unpack it like a tuple.

~~You probably want something like this~~ You can translate your code into something that works like this:

```auto
for row in pyDataset:
    for key, value in zip(pyDataset.columnNames, row):
        message = 'key: ' + key + ', value: ' + value
        system.perspective.print(message)

```

But let's avoid the XY problem and maybe ask what you're actually trying to do 🙂

---

<div class="post-metadata">

**Author:** ![ian.sebryk](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ian.sebryk/32/49319_2.png) [@ian.sebryk](https://forum.inductiveautomation.com/u/ian.sebryk)\
**Post date:** [July 14, 2023, 9:31pm UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415/3 "2023-07-14T21:31:40Z")

</div>

same as with every data structure: SEE how it's laid out, see the keys and values, see the nesting. just like a simple unpacking of a JSON object or a dict. some of these scripts are making no sense because they are targeting things that don't exist in the dataset in the user's tag. eg. `row['visibility']` when there is no such column. and if we change it to `isVisible`, the actual name, the script breaks. so i want to just see the raw data without all the UI. show me keys, values, and indicies. like this:

```python
{
    'docs_url': None,
    'download_url': 'UNKNOWN',
    'downloads': {...},
    'home_page': 'https://github.com/pypa/sampleproject',
    'keywords': 'sample setuptools development',
    'license': 'MIT',
}

```

so now i know that`docs_url` has a value of `None`, `downloads` is going to be a `dict`, and that they aren't zero-based indexed, like a `list` would be. moreover, i know that `keywords` comes AFTER `downloads`, and not before. this is basic, basic stuff in just about any coding language: Py, JS, PHP.

EDIT: your script also fails, btw: `cannot concatenate 'unicode' and 'bool'`

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 14, 2023, 9:58pm UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415/4 "2023-07-14T21:58:01Z")

</div>

Default Java and python2 dictionaries are not order-preserving. This creates, along with Perspective's property wrapper quirks, a number of fundamental issues that cause programmers from other disciplines to pull their hair out.

I'm not aware of any learning curve shortcuts for someone on a deadline. Keep asking questions here--we'll keep helping.

Much of what you are struggling with [is documented](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.27/index.html), but the java way, and therefore time-consuming to absorb. 🤷‍♂️

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 14, 2023, 10:00pm UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415/5 "2023-07-14T22:00:36Z")

</div>

> [@ian.sebryk](#):
>
> EDIT: your script also fails, btw: `cannot concatenate 'unicode' and 'bool'`

Well, that's a bog-standard Python error. Using a better formatting construct should help:

```auto
for row in pyDataset:
    for key, value in zip(pyDataset.columnNames, row):
        system.perspective.print('key: {}, value: {}'.format(key, value))

```

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [July 15, 2023, 5:43pm UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415/6 "2023-07-15T17:43:51Z")

</div>

> [@ian.sebryk](#):
>
> ` for key, value in row:`

Note that this wouldn't work for `dict`s either, you'd need to use `row.items()` to extract both the key and values.

---

<div class="post-metadata">

**Author:** ![ian.sebryk](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ian.sebryk/32/49319_2.png) [@ian.sebryk](https://forum.inductiveautomation.com/u/ian.sebryk)\
**Post date:** [July 17, 2023, 1:47pm UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415/7 "2023-07-17T13:47:37Z")

</div>

wait... Python **2**!?!? how did i not know this? um, yeah. back to unordered _everything_... oh, wow. ok. that actually explains many other things i thought were odd elsewhere in the project. can't believe i didn't check that sooner.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [July 17, 2023, 2:20pm UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415/8 "2023-07-17T14:20:19Z")

</div>

> [@ian.sebryk](#):
>
> wait... Python **2**!?!? how did i not know this?

Specifically 2.7, and it's Jython which can sometimes make a difference, like not supporting C extensions (e.g. numpy)

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 17, 2023, 3:30pm UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415/9 "2023-07-17T15:30:26Z")

</div>

> [@lrose](#):
>
> it's Jython which can sometimes make a difference

Jython still has not made the leap to v3, mainly because the key motivators for the 2=\>3 breaking change aren't such big deals in Jython. Specifically:

- Jython strings are already internationalized, as they are wrappers for java strings (which are 16-bit wide characters under the hood). Java bytes and byte arrays, used and delivered by java's filesystem and stream libraries, already provide the basis for the distinction between bytes and characters that Python3 introduced.

- CPython's global interpreter lock doesn't exist in Jython. Jython is fully multithreaded out of the box, and all of the core Python data structures (sequences, mapping types) are built on Java `Concurrent` collections--a thread-safe foundation. This doesn't mean an _algorithm_ implemented in jython will be thread-safe, but that such algorithms do not suffer the interpreter contention of CPython.

- CPython's async and await keywords are the stop-gap alternative for full, high-performance multi-threading. Jython doesn't need these, partly because its multi-threading doesn't suck, but mainly because java provides a complete set of functional programming tools that a jython application can leverage. And are preferred, as they will interoperate with native java objects.

On top of that, jython makes interaction with java libraries almost trivially easy. Java types can be imported by name, and java classes are implicitly treated as constructors, python style. When any java object is encapsulated for use by the jython interpreter, it is **wrapped** in a jython type that automatically recognizes NetBeans-compliant getters and setters, and inserts python property handlers for them. So, any `.getSomething()` can (and should) be shortened to just `.something`. Likewise, any `.setSomething(rhs)` can be written as the statement `.something = rhs`.

Finally, note that java has high-performance ordered mappings that can (and should) be used in place of python's `orderedDict`. I tend to use `LinkedHashMap` for throw-away computations, and apply [Collections.synchronizedMap()](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collections.html#synchronizedMap(java.util.Map)) if I need a thread-safe version.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [May 8, 2024, 10:42pm UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415/10 "2024-05-08T22:42:26Z")

</div>

> [@pturmel](#):
>
> So, any `.getSomething()` can (and should) be shortened to just `.something`

Why "should"? I do because it's shorter, but is there a performance reason as well?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 8, 2024, 11:11pm UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415/11 "2024-05-08T23:11:35Z")

</div>

Yes, the former is two jython bytecode operations, and the latter is just one.

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [May 9, 2024, 12:08am UTC](https://forum.inductiveautomation.com/t/printing-key-value-pairs-from-pydataset/76415/12 "2024-05-09T00:08:51Z")

</div>

Thanks! 🙂
