Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a large list with varying constituent parts. Some of these are like this:

i.e. graphlist[[34]]

{{{33, 0.0115084}}, {{33, 0.00539003}}, {{33, 0.0158185}}, 
 {{33, 0.0136278}}, {{33, 0.00756737}}, {{33, 0.0017506}}, 
 {{33, 0.038599}}, {{33, 0.00538894}}, {{33, 0.00656522}},
 {{33, 0.00310004}}, {{33, 0.00151645}}, {{33, 7.75*10^-7}},
 {{33, 0.00205609}}, {{33, 0.00125328}}}

Whereas others are like this:

graphlist[[1]]

{{}, {{0, 0.00342769}}, {{0, 0.00503465}}, {}, 
 {{0, 0.000187}}, {}, {}, {}, {}, {}, {}, {}, {}, {}}

Because they are all part of a long list, I'm trying to find a command that can do the following. On a list without any null values, I am running this command to get the second part:

graphlist[[34]][[All, 1]][[All, 2]]

> {0.0115084, 0.00539003, 0.0158185, 0.0136278, 0.00756737, 0.0017506, 
> 0.038599, 0.00538894, 0.00656522, 0.00310004, 0.00151645, 
>  7.75*10^-7, 0.00205609, 0.00125328}

But if I run a similar command on the list with nulls, the error message: "Part::partw: Part 1 of {} does not exist. >>" ensues. My goal is to similarly get output that would look like this:

{0,0.00342769,0.00503465,0,0.000187,0,0,0,0,0,0,0,0,0}

Is there a way to construct a command that simply returns a 'zero' value for empty brackets? Thanks in advance.

share|improve this question
    
"My goal is to similarly get output that would look like this" are the values in your final example second elements? –  Mike Honeychurch Jul 28 '12 at 4:03
    
@MikeHoneychurch Sorry, I should have been specific - they are. –  programming_historian Jul 28 '12 at 4:04
add comment

5 Answers

up vote 2 down vote accepted

With

l1 = {{{33, 0.0115084}}, {{33, 0.00539003}}, {{33, 0.0158185}}, {{33, 
     0.0136278}}, {{33, 0.00756737}}, {{33, 0.0017506}}, {{33, 
     0.038599}}, {{33, 0.00538894}}, {{33, 0.00656522}}, {{33, 
     0.00310004}}, {{33, 0.00151645}}, {{33, 7.75*10^-7}}, {{33, 
     0.00205609}}, {{33, 0.00125328}}};
l2 = {{}, {{0, 0.00342769}}, {{0, 0.00503465}}, {}, {{0, 
     0.000187}}, {}, {}, {}, {}, {}, {}, {}, {}, {}};

you can do this:

If[# === {}, 0, #[[1, 2]]] & /@ l1
{0.0115084, 0.00539003, 0.0158185, 0.0136278, 0.00756737, 0.0017506, 0.038599, 0.00538894, 0.00656522, 0.00310004, 0.00151645, 7.75*10^-7, 0.00205609, 0.00125328}


If[# === {}, 0, #[[1, 2]]] & /@ l2
{0, 0.00342769, 0.00503465, 0, 0.000187, 0, 0, 0, 0, 0, 0, 0, 0, 0}
share|improve this answer
add comment

Why not delete the {} before carrying out any further analysis?

newgraphlist = 
 DeleteCases[{{}, {{0, 0.00342769}}, {{0, 0.00503465}}, {}, {{0, 
     0.000187}}, {}, {}, {}, {}, {}, {}, {}, {}, {}}, {}]

...but if you want zeros then you can use a rule replacement

graphlist /. {} -> 0

In your final example it looks like you are taking all the second elements so

newgraphlist = graphlist /. {} -> {{0, 0}}
newgraphlist[[All, 1, 2]]
share|improve this answer
add comment
l = {{}, {{0, 0.00342769}}, {{0, 0.00503465}}, {}, {{0, 0.000187}}, {}, {}, {}, {}, {}, {}, {}, {}, {}}
List /@ Sequence @@@ l
(*
-> {{{0, 0.00342769}}, {{0, 0.00503465}}, {{0, 0.000187}}}
*)

Or

l /. {} -> 0
(*
{0, {{0, 0.00342769}}, {{0, 0.00503465}}, 0, {{0, 0.000187}}, 0, 0, 0, 0, 0, 0, 0, 0, 0}
*)

Or

Last /@ Sequence @@@ (l /. {} -> {{0}})
(*
-> {0, 0.00342769, 0.00503465, 0, 0.000187, 0, 0, 0, 0, 0, 0, 0, 0, 0}
*)

Depending on what you really want as a result :)

share|improve this answer
add comment

If you wish to get rid of the {}, then Mike's answer using DeleteCases works in this particular case, but will fail in general, because it will not remove {} that's nested deeper (such as {{}}). Using ReplaceAll or /. also fails in some cases because it removes it from inside any head. For example, if you have {a, {}, {{}}, f[b, {}]}, the expected behaviour is to not remove the {} from inside f. The proper way to do it, as outlined in this answer on Stack Overflow is:

expr = {a, {}, {{}}, f[b, {}]};
Replace[expr, x_List :> DeleteCases[x, {}], {0, Infinity}]
(* {a, f[b, {}]} *)

So for your expression in graphlist[[1]], it would give:

Replace[graphlist[[1]], x_List :> DeleteCases[x, {}], {0, Infinity}]
(* {{{0, 0.00342769}}, {{0, 0.00503465}}, {{0, 0.000187}}} *)

EDIT

An alternative using ReplaceAll could be

expr /. {i : Except[_List] :> i, l_ /; Flatten[l] === {} :> Sequence[]}

or more compactly using ReplaceRepeated (probably not as efficient)

expr //. {i : Except[_List] :> i, {} :> Sequence[]}
share|improve this answer
    
I like yours best, but it can be done properly with ReplaceAll too. expr /. {i : Except[_List] :> i, l_ /; Flatten[l] === {} :> Sequence[]} –  Rojo Jul 28 '12 at 16:09
    
@Rojo I like it! More than mine, actually. I was referring to /. {} -> Sequence[] in that statement though. I think yours is more reasonable in this corner case: expr = {{}, a, {{}}, f[{{{}}}]}. "Reasonable" of course depends on the intent — the objective in the linked question was to remove all {} if it is inside another list, which mine does, but I think I would intuitively expect the behaviour in yours. Feel free to edit it into my answer (or if you write a new one, I'll upvote it) –  rm -rf Jul 28 '12 at 16:32
add comment

With

list = {{}, {{0, 0.00342769`}}, {{0, 0.00503465`}}, {}, {{0, 0.000187`}}, {}, {}, {}, {}, {}, {}, {}, {}, {}};

Several alternatives in addition to previous answers:

Last @@@ (list /. {} -> {{0, 0}})

gives

(* {0, 0.00342769, 0.00503465, 0, 0.000187, 0, 0, 0, 0, 0, 0, 0, 0, 0} *)

So do

list //. {{} -> {{0, 0}}, {{_, x_}} :> x}

and

Replace[list, {{} -> 0, {{_, x_}} :> x}, {1}]

the latter thanks to Mr.Wizard.

share|improve this answer
    
You would do better to use: Replace[list, {{} -> 0, {{_, x_}} :> x}, {1}] -- this way you only scan the list once. You should use :> for named patterns on the RHS. +1 nevertheless –  Mr.Wizard Jul 28 '12 at 9:05
    
@Mr.Wizard, great point. And thank you for the vote. –  kguler Jul 28 '12 at 9:15
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.