Re: Identical elements
- To: mathgroup at smc.vnet.net
- Subject: [mg88427] Re: Identical elements
- From: tommcd <TCMcDermott at gmail.com>
- Date: Mon, 5 May 2008 06:12:49 -0400 (EDT)
- References: <fvhe2h$3th$1@smc.vnet.net>
On May 3, 11:16 am, KFUPM <hussain.alqaht... at gmail.com> wrote: > Dear All > > I have a list and i need to test whether all the elements in the list > are identical or no. What is the efficient way to do that? The output > should be true if all elements are the same and False otherwise. One > line command is preferred if possible. > > Your help is highly appreciated. > > Regards, > > HMQ Short answer: Count[x, x[[1]]] == Length[x] seems efficient, especially for the case of large lists with most elements equal. Longer: As I've only very recently started to use Mathematica for 'programming' I thought I'd try a few different ways : >From below you can see that count is best, followed by the Do loop version. Side note: Coding the Do loop version was very traumatic for this Fortran programmer as I've just learned that Return behaves much differently in a Do loop than in a For or While loop. And the behaviour which to me seems more consistent (i.e same as For and While) can only be got by using the Return[_,Module] form which is not documented & I only discovered by searching this newsgroup. Moreover the current documentation (6.02) for return is sparse and doesn't really explain any of this clearly. When I do need a loop I prefer Do as it's simple (and close to the Fortran do loop in style so easy for quick conversion) and has the advantage that the looping variables are localized. I know procedural programming is not encouraged in Mathematica but sometimes the flow of control is messy & it's not possible to reduce a block of code to a small function let alone a one liner. I'm now not sure how a given Return[] nested in various loops an other control structures behaves (other than by testing it by trial and error), and since the Return[_,Module] is undocumented I guess it's not safe to use. I know there's Throw/Catch etc. and the real problem is I expected Return to behave like in Fortran/C, but I think this does warrant one or two sentences in the documentation as quite a few programmers must come to Mathematica from Fortran &/ C++. Regards, Tom McDermott. In[1]:= f1[x_] := Module[{x1 = x[[1]], i, n = Length[x]}, For[i = 2, i <= n, i++, If[x[[i]] != x1, Return[False]]]; True] In[2]:= f2[x_] := Module[{x1 = x[[1]], n = Length[x]}, Do[If[x[[i]] != x1, Return[False, Module]];, {i, 2, n}]; True] In[3]:= f3[x_] := And @@ (# == x[[1]] & /@ x) In[4]:= f4[x_] := Module[{x1 = x[[1]]}, And @@ (# == x1 & /@ x)] In[5]:= f5[ x_] := (Scan[If[# != x[[1]], Return[False]] &, x] === Null) In[6]:= f6[x_] := Module[{x1 = x[[1]]}, (Scan[If[# != x1, Return[False]] &, x] === Null)] In[7]:= f7[x_] := LengthWhile[x, # == x[[1]] &] == Length[x] In[8]:= f8[x_] := Count[x, x[[1]]] == Length[x] In[9]:= t = ConstantArray[0, {9, 7}]; Do[ For[n = 1; i = 1, n < 10^7, n *= 10; i++, x = ConstantArray[1, {n}]; (*x=RandomInteger[{1,n},n];*) x[[RandomInteger[{1, n}]]] = 0; t[[1, i]] += n; j = 1; Do[ j++; t[[j, i]] += Timing[f[x]][[1]]; , {f, {f1, f2, f3, f4, f5, f6, f7, f8}} ] ] , {k, 10} ]; MatrixForm[t/10] Out[10]//MatrixForm= \!\(\* TagBox[ RowBox[{"(", "\[NoBreak]", GridBox[{ {"1", "10", "100", "1000", "10000", "100000", "1000000"}, {"6.083675230250663`*^-16", "5.078402975922103`*^-16", "7.919012667834124`*^-16", "0.001299800000000279`", "0.013097899999999621`", "0.11298270000000028`", "1.1733215999999995`"}, {"6.083675230250663`*^-16", "0.00010000000000050794`", "7.919012667834124`*^-16", "0.0005999999999994859`", "0.0074988999999999655`", "0.06299050000000009`", "0.6567000999999999`"}, {"6.083675230250663`*^-16", "7.409871327634932`*^-16", "0.0003999000000004959`", "0.00119989999999912`", "0.01059839999999971`", "0.10818369999999931`", "1.0992327999999991`"}, {"5.079270337660091`*^-16", "0.00010000000000074099`", "0.00010000000000089772`", "0.0007998000000010313`", "0.007098899999999141`", "0.07198899999999954`", "0.7474868000000006`"}, {"5.079270337660091`*^-16", "7.919012667834124`*^-16", "0.0001999000000005075`", "0.0007998000000009498`", "0.007598899999999501`", "0.06838960000000004`", "0.7099917000000004`"}, {"5.079270337660091`*^-16", "7.919012667834124`*^-16", "5.845991008987528`*^-16", "0.0006000000000008052`", "0.006199100000000433`", "0.05239210000000059`", "0.5442175999999997`"}, {"0.00010000000000050794`", "0.00010000000000047177`", "0.0001000000000005846`", "0.00149979999999977`", "0.01489779999999977`", "0.12608060000000074`", "1.2976026000000003`"}, {"5.078402975922103`*^-16", "7.919012667834124`*^-16", "5.845096542195228`*^-16", "4.1227871810933796`*^-16", "0.000699799999999542`", "0.00899880000000006`", "0.09288559999999928`"} }, GridBoxAlignment->{ "Columns" -> {{Left}}, "ColumnsIndexed" -> {}, "Rows" -> {{Baseline}}, "RowsIndexed" -> {}}, GridBoxSpacings->{"Columns" -> { Offset[0.27999999999999997`], { Offset[0.7]}, Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> { Offset[0.2], { Offset[0.4]}, Offset[0.2]}, "RowsIndexed" -> {}}], "\[NoBreak]", ")"}], Function[BoxForm`e$, MatrixForm[BoxForm`e$]]]\) Side note: (maybe some gure can comment on this gripe)... Coding the Do loop version was very traumatic for this Fortran programmer as I've just learned that Return behaves much differently in a Do loop than in a For or While loop. And the behaviour which to me seems more consistent (i.e same as For and While) can only be got by using the Return[_,Module] form which is not documented & I only discovered by searching this newsgroup. Moreover the current documentation (6.02) for return is sparse and doesn't really explain any of this clearly. When I do need a loop I prefer Do as it's simple (and close to the Fortran do loop in style so easy for quick conversion) and has the advantage that the looping variables are localized. I know procedural programming is not encouraged in Mathematica but sometimes the flow of control is messy & it's not possible to reduce a block of code to a small function let alone a one liner. I'm now not sure how a given Return[] nested in various loops an other control structures behaves (other than by testing it by trial and error), and since the Return[_,Module] is undocumented I guess it's not safe to use. I know there's Throw/Catch etc. and the real problem is I expected Return to behave like in Fortran/C, but I think this does warrant one or two sentences in the documentation as quite a few programmers must come to Mathematica from Fortran &/ C++.