-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support guards/filters in comprehensions #550
Comments
Jeff's workaround for this particular case is fine, but in general guards could include multiple comprehension variables, as in the Cartesian product except the diagonal:
I don't see how to get there with the current list comprehension capabilities. |
I call what we have array comprehensions. The size of the output array is determined by the ranges before the computation starts, and that would be difficult with guards. One could always extract a subarray at the end though, if guards are used, and they should not be too difficult to implement either. We do need to debate if we want this, and the actual syntax. @StefanKarpinski Given that you came up with the original comprehensions idea, what are your thoughts? |
Filters and guards don't mix with multidimensional comprehensions. For 1-d comprehensions, I'm not convinced that it's really worth the additional syntax. What's the case for making it part of the syntax instead of just using a filter function? |
/edit. here was something else, but it was BS. I don't see the advantage of guards to array slices a la x[x>3], but it don't see the problem with multi dimensions since the slices already operate on multi dimension arrays. multiple comprehension variables would be cool thou, but I think it would be cooler this way:
|
Because it doesn't work in higher dimensions: you can't just excise arbitrary items out of a matrix and still get a matrix. |
One could set values to be excised to zero or some other default provided by the user. One could implement diag, triu, tril, spdiags, etc. using comprehensions. This kind of stuff would be great for experimenting and exploration. However, these would be bad implementations, since even though the running time complexity is the same, one ends up consuming many more flops than necessary. -viral On 09-Mar-2012, at 3:24 PM, Stefan Karpinski wrote:
|
Today the output is always one dimensional. Or am i missing something? |
Above comments re: full array comprehensions seem reasonable. There are contexts (like the Cartesian product minus the diagonal) where you'd be okay with that array flattened, and some where you would really prefer to never evaluate "invalid" pairs:
It might be the case that we'd rather this idiom be written with a |
@rtzui Try |
I've written a small patch for the manual to mention the Cartesian |
I guess this could be implemented by transforming 1d comprehensions with guards to loops using |
That's a solid idea. Another option would be to pre-allocate the whole thing and then shrink at the end. Might want to choose between the two approaches based on a threshold. (Guards would still only work in the 1d case.) |
This is pretty absurd, but with https://gist.github.com/3677645 (UPDATE 2013-04-03: or Monads.jl) you can do:
|
Would be good have a while sentence for list comprehension too. |
I would like to write Symmetric matrices using list comprehension:
or why not, something like
Maybe some operator, like
Maybe symmetric matrix type can be a vector for only the upper o lower part, with special |
S = [1, -1, 2, -2, 0] As mentioned in dupe issues, comprehensions in other languages allow something along the lines of [x for x in S if x > 0] The work around for this problem seems to be S[[x for x in S] .> 0] Is this going to be the preferred choice? Or is there a more Julian way? |
There is of course the filter(x -> x > 0, S) but this is getting further from the beauty of comprehension syntax. |
|
It's O(2n), but that 2 is pretty important. |
Yeah, I think the whole I idea of comprehension filtering is that the filtering is happening during construction, like using an |
I've come around to the idea that having an [ver for (ver,info) in avail if head == info.sha1] This is pretty hard to express otherwise. It can be done with filter and then map, but it's a bit awkward: [keys(filter((ver,info)->head == info.sha1, avail))...] This took me several minutes to get right. Having an |
+1 for allowing |
I hate to suggest syntax, but |
It's a bit awkward, but it just kind of falls out and isn't the worst idiom I've ever seen. |
another +1 for allowing filters and forcing 1D array |
Has been any update on this subject? L = [ i for i in R if i%2 > 0] # OK: returns a 1D array
L = [ i+j for i in R, j in S if i>j] # ERROR: 'if' not allowed in matrix comprehensions
L = [ i+j for i in R for j in S if i>j ] # OK: returns a 1D array (a la Python)
L = [ i+j for i=1:10 for j=i:10 if (i+j)%2==0 ] # OK: returns a 1D array I think in this way array comprehensions are perfectly clear and it doesn't mess the current syntax. |
I like Raul's idea for syntax. Any updates on this? I would help if I wasn't such a noob! It would make Julia more attractive I think... I used list comprehensions with guards all the time in Python and they saved a lot of time/space. |
S[S.> 0] |
What is the future/present of this now that generators exist? |
I know there's been a lot of discussion around final 0.5 feature triage, but I think this would be a great candidate. I'd hate for us to release 0.5 with generators only to have python-users everywhere wonder why this didn't come with it. From the discussion in #15023, it sounds like a pretty straightforward parsing re-write, which does limit the number of devs who'd feel comfortable making the change, but I think it'd be well worth it. |
👍 |
I think @StefanKarpinski's proposed placement of x^2 if x % 3 == 0 for x = 1:100 # versus
x^2 for x = 1:100 if x % 3 == 0 |
this also uses the new lowering for typed comprehensions, allowing all comprehensions on unknown-length iterables (fixes #1457)
this also uses the new lowering for typed comprehensions, allowing all comprehensions on unknown-length iterables (fixes #1457)
this also uses the new lowering for typed comprehensions, allowing all comprehensions on unknown-length iterables (fixes #1457)
this also uses the new lowering for typed comprehensions, allowing all comprehensions on unknown-length iterables (fixes #1457)
JuliaLang#4867) this also uses the new lowering for typed comprehensions, allowing all comprehensions on unknown-length iterables (fixes JuliaLang#1457)
Add another generalization for r2 to GLM that uses the deviance ratio. Change the last line of the docs to state that it corresponds to mss/tss for OLS.
Stdlib: SparseArrays URL: https://github.com/JuliaSparse/SparseArrays.jl.git Stdlib branch: main Julia branch: master Old commit: e61663a New commit: 55976a6 Julia version: 1.12.0-DEV SparseArrays version: 1.12.0 Bump invoked by: @ViralBShah Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: JuliaSparse/SparseArrays.jl@e61663a...55976a6 ``` $ git log --oneline e61663a..55976a6 55976a6 Keep sparse solvers docs as before (#552) 95fd7ff Missing space in error message (#554) b8a13ef implement in-place `ldiv!` for Cholesky factorization (#547) 1527014 Do not use nested dissection by default. (#550) ``` Co-authored-by: Dilum Aluthge <[email protected]>
…aLang#55469) Stdlib: SparseArrays URL: https://github.com/JuliaSparse/SparseArrays.jl.git Stdlib branch: main Julia branch: master Old commit: e61663a New commit: 55976a6 Julia version: 1.12.0-DEV SparseArrays version: 1.12.0 Bump invoked by: @ViralBShah Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: JuliaSparse/SparseArrays.jl@e61663a...55976a6 ``` $ git log --oneline e61663a..55976a6 55976a6 Keep sparse solvers docs as before (JuliaLang#552) 95fd7ff Missing space in error message (JuliaLang#554) b8a13ef implement in-place `ldiv!` for Cholesky factorization (JuliaLang#547) 1527014 Do not use nested dissection by default. (JuliaLang#550) ``` Co-authored-by: Dilum Aluthge <[email protected]>
8c84b8c (#56431) Stdlib: SparseArrays URL: https://github.com/JuliaSparse/SparseArrays.jl.git Stdlib branch: release-1.10 Julia branch: backports-release-1.10 Old commit: 279b363 New commit: 8c84b8c Julia version: 1.10.6 SparseArrays version: 1.10.0(Does not match) Bump invoked by: @IanButterworth Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: JuliaSparse/SparseArrays.jl@279b363...8c84b8c ``` $ git log --oneline 279b363..8c84b8c 8c84b8c Merge pull request #572 from JuliaSparse/backports-release-1.10 ec38631 Update ci.yml with more architectures 46c8f7e Merge branch 'release-1.10' into backports-release-1.10 2d762b3 Manual commit for PR #550 to backport to 1.10 (#577) 5c37298 Add versions to include arch b539588 Update CI fa49620 Disable nested dissection d2a80a6 Change default QR tolerance to match SPQR (#557) 9b8cd14 SparseMatrixCSC constructor with a Tuple of Integers (#523) 546be18 Fix docs conflict when building as part of full Julia docs (#430) 30fbfc6 Test suite: activate a temp project if we need to install Aqua.jl during the test suite (#425) 91b0aa5 doc: move solvers doc to `src\solvers.md` (#576) 5d3724a Inline sparse-times-dense in-place multiplication ``` Co-authored-by: Dilum Aluthge <[email protected]>
8c84b8c (#56431) Stdlib: SparseArrays URL: https://github.com/JuliaSparse/SparseArrays.jl.git Stdlib branch: release-1.10 Julia branch: backports-release-1.10 Old commit: 279b363 New commit: 8c84b8c Julia version: 1.10.6 SparseArrays version: 1.10.0(Does not match) Bump invoked by: @IanButterworth Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: JuliaSparse/SparseArrays.jl@279b363...8c84b8c ``` $ git log --oneline 279b363..8c84b8c 8c84b8c Merge pull request #572 from JuliaSparse/backports-release-1.10 ec38631 Update ci.yml with more architectures 46c8f7e Merge branch 'release-1.10' into backports-release-1.10 2d762b3 Manual commit for PR #550 to backport to 1.10 (#577) 5c37298 Add versions to include arch b539588 Update CI fa49620 Disable nested dissection d2a80a6 Change default QR tolerance to match SPQR (#557) 9b8cd14 SparseMatrixCSC constructor with a Tuple of Integers (#523) 546be18 Fix docs conflict when building as part of full Julia docs (#430) 30fbfc6 Test suite: activate a temp project if we need to install Aqua.jl during the test suite (#425) 91b0aa5 doc: move solvers doc to `src\solvers.md` (#576) 5d3724a Inline sparse-times-dense in-place multiplication ``` Co-authored-by: Dilum Aluthge <[email protected]>
…to 2420351 (#56608) Stdlib: SparseArrays URL: https://github.com/JuliaSparse/SparseArrays.jl.git Stdlib branch: release-1.11 Julia branch: backports-release-1.11 Old commit: cb602d7 New commit: 2420351 Julia version: 1.11.1 SparseArrays version: 1.11.0(Does not match) Bump invoked by: @dkarrasch Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: JuliaSparse/SparseArrays.jl@cb602d7...2420351 ``` $ git log --oneline cb602d7..2420351 2420351 Allow for duplicate docstrings in linalg docs (#584) 0a1c886 Merge pull request #571 from JuliaSparse/backports-release-1.11 298f5e1 Break recursion (#579) 7bc65ab Update CI fcc6102 Do not use nested dissection by default. (#550) 8534357 Update ci.yml: run CI and docs on v1.11 66d65fd Change default QR tolerance to match SPQR (#557) 8a48327 test: Don't use GPL module when Base.USE_GPL_LIBS=false (#535) 8dd8300 SparseMatrixCSC constructor with a Tuple of Integers (#523) aa66624 doc: move solvers doc to `src\solvers.md` (#576) 8a85fbe Inline sparse-times-dense in-place multiplication ``` Co-authored-by: Dilum Aluthge <[email protected]>
Quoting @rtzui in #547:
On the other hand more powerful:
(Discussion from @pao)
There is an open syntactic question. The Haskell syntax (shown above) has guards as boolean expressions separated by commas and interspersed with membership assertions, which works as long as you can tell the difference between an expression evaluating to a boolean and a loop assignment statement. Python uses the keyword "if" to precede each guard. I'm sure there are other approaches as well.
(From @JeffBezanson)
It's maybe not ideal, but you can accomplish this as:
The text was updated successfully, but these errors were encountered: