convert.from_json and convert.from_yaml accept default as a list when… - #987
Conversation
… input is also a list
|
@mborodii-prog : this 3rd behavior is confusing / too 'magical':
I would recommend we stick to 2 behaviors only:
This will meet the typical use cases and is easy to understand. |
|
@ebhills now we support:
|
thomasstvr
left a comment
There was a problem hiding this comment.
Can you add a test (for both yaml and json) that uses more complex defaults and does not list outputs?
wrangles:
- convert.from_json:
input:
- header1
- header2
default:
- my_output:
key1: Val1
key2: Val2
- [this, is, a, list]A few small changes, but looks good otherwise
|
@thomasstvr Added two new tests (test_default_list_complex_values_no_output) to TestConvertFromJSON and TestConvertFromYAML covering complex per-column defaults (a nested dict and |
ebhills
left a comment
There was a problem hiding this comment.
the code looks correct, but the input data for a couple of the tests seem off. is this intentional to see if the default kicks in? the assertions do not seem to suggest that is the goal.
…h their default types
There was a problem hiding this comment.
Maybe an edge case bug? Maybe in the yaml parsing, not the defaults?
- convert.from_yaml:
input:
- Top *
default:
- {}
- []
- ''
- convert.to_yaml:
input:
- Top *I think this should be reversible, right? But row 2 comes out differently. I am running with batch size 1 so this may result of colm shifting i identified on the empty where df PR.
(first 3 columns are input)
raw input data:
Top 12 Top 23 Top 34
"Score: 0.295
Value: Blade Runner
" "[]
" "Score: 0.174
Value: Westworld
"
"Score: 0.234
Value: Interstellar
" "Score: 0.22
Value: Westworld
" "'
"
"Score: 0.291
Value: Interstellar
" "Score: 0.248
Value: Blade Runner
" "Score: 0.195
Value: Westworld
"
Now that I have pasted the data it makes me wonder why all of those "s are there.
The input columns were generated from running a previous version of the recipe where the first wrangle was from_json on this data:
Top 1 Top 2 Top 3
{"Score":0.295,"Value":"Blade Runner"} {"Score":0.174,"Value":"Westworld"}
{"Score":0.234,"Value":"Interstellar"} {"Score":0.22,"Value":"Westworld"}
{"Score":0.291,"Value":"Interstellar"} {"Score":0.248,"Value":"Blade Runner"} {"Score":0.195,"Value":"Westworld"}
|
@ebhills pls check now that behavior in QA |
|
@ebhills @thomasstvr you can use recipe - convert.from_yaml:
|
|
@thomasstvr - you also need to approve this one since you had requested changes |
Summary
convert.from_jsonandconvert.from_yamlnow accept a list of defaults wheninputis also a list of columns. Previously, passingdefaultas a YAML list (e.g.default: - {}) caused an error because only scalar defaults were supported.Behaviour
defaultvalueinputcolumns{},null,0, …)[]— empty list[]used as the default for every column[value]— 1-element listvalueand broadcast to all columns[v1, v2, …]— n-element list[v1, v2, v3]— n-element listValueError(length mismatch)Examples
1 — Original issue: single column with a list-style default
'{"a": 1}'{"a": 1}''{}'bad json'{}2 — One default broadcast across multiple columns
'{"a":1}''{"b":2}'{"a": 1}{"b": 2}''''{}{}3 — Different default per column
'{"a":1}''[1,2,3]'{"a": 1}[1, 2, 3]''''{}[]4 — Same patterns work for
convert.from_yaml5 — Empty list as a default value (pre-existing behaviour preserved)
'[1,2,3]'[1, 2, 3]''[]6 — Length mismatch raises an error
Implementation notes
isinstance(default, list) and len(default) > 0. An empty list ([]) is unambiguously a default value, not a zero-length per-column list, so it falls through to the scalar broadcast path.[value]) is always unwrapped and broadcast regardless of how many input columns there are.